Skip to content

Missing(Porting) SaveAS API to HttpPostedFile #459

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ internal HttpPostedFile() { }
public string ContentType { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public string FileName { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public System.IO.Stream InputStream { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public void SaveAs(string filename) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
}
public abstract partial class HttpPostedFileBase
{
Expand All @@ -322,6 +323,7 @@ public abstract partial class HttpPostedFileBase
public virtual string ContentType { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public virtual string FileName { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public virtual System.IO.Stream InputStream { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public virtual void SaveAs(string filename) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
}
public partial class HttpPostedFileWrapper : System.Web.HttpPostedFileBase
{
Expand All @@ -330,6 +332,7 @@ public partial class HttpPostedFileWrapper : System.Web.HttpPostedFileBase
public override string ContentType { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public override string FileName { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public override System.IO.Stream InputStream { get { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");} }
public override void SaveAs(string filename) { throw new System.PlatformNotSupportedException("Only supported when running on ASP.NET Core or System.Web");}
}
public partial class HttpRequest
{
Expand Down
15 changes: 15 additions & 0 deletions src/Microsoft.AspNetCore.SystemWebAdapters/HttpPostedFile.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Globalization;
using System.IO;
using Microsoft.AspNetCore.Http;

Expand All @@ -19,4 +20,18 @@ public sealed class HttpPostedFile
public int ContentLength => (int)File.Length;

public Stream InputStream => File.OpenReadStream();

public void SaveAs(string filename)
{
if (!Path.IsPathRooted(filename))
{
throw new HttpException(string.Format(CultureInfo.InvariantCulture,
"The SaveAs method is configured to require a rooted path, and the path '{0}' is not rooted", filename));
}

using (var fileStream = new FileStream(filename, FileMode.Create))
{
InputStream.CopyTo(fileStream);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ public abstract class HttpPostedFileBase
public virtual int ContentLength => throw new NotImplementedException();

public virtual Stream InputStream => throw new NotImplementedException();

public virtual void SaveAs(string filename) => throw new NotImplementedException();
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ public HttpPostedFileWrapper(HttpPostedFile httpPostedFile)
public override string FileName => _file.FileName;

public override Stream InputStream => _file.InputStream;

public override void SaveAs(string filename) => _file.SaveAs(filename);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Globalization;
using System;
using System.IO;
using System.Web;
using AutoFixture;
Expand Down Expand Up @@ -100,4 +102,37 @@ public void InputStream()
// Assert
Assert.Equal(expected.Object, stream);
}

[Fact]
public void SaveAsForInvalidRootPath()
{
// Arrange
var file = new Mock<IFormFile>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you follow the arrange/act/assert pattern as above? Can you add a test for something rooted? maybe to the temp directory?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@twsouthwick does this look ok ? (Dividing into 2 separate test cases)

    [Fact]
    public void SaveAsForInvalidRootPath()
    {
        // Arrange
        var file = new Mock<IFormFile>();
        var expectedStream = new Mock<Stream>();
        file.Setup(f => f.OpenReadStream()).Returns(expectedStream.Object);
        var posted = new HttpPostedFile(file.Object);

        //Act and Assert
        Assert.Throws<HttpException>(() => posted.SaveAs("InvalidPath"));
    }

    [Fact]
    public void SaveAsWithValidRootPath()
    {
        // Arrange
        var file = new Mock<IFormFile>();
        var expectedStream = new Mock<Stream>();
        file.Setup(f => f.OpenReadStream()).Returns(expectedStream.Object);
        string validTempPath = string.Format(CultureInfo.InvariantCulture, @"{0}{1}.txt", Path.GetTempPath(), Guid.NewGuid());
        var posted = new HttpPostedFile(file.Object);

        //Act
        posted.SaveAs(validTempPath);

        //Assert
        Assert.True(File.Exists(validTempPath), "Temp file should be created");

        //Cleanup
        File.Delete(validTempPath);
    }

var expectedStream = new Mock<Stream>();
file.Setup(f => f.OpenReadStream()).Returns(expectedStream.Object);
var posted = new HttpPostedFile(file.Object);

//Act and Assert
Assert.Throws<HttpException>(() => posted.SaveAs("InvalidPath"));
}

[Fact]
public void SaveAsWithValidRootPath()
{
// Arrange
var file = new Mock<IFormFile>();
var expectedStream = new Mock<Stream>();
file.Setup(f => f.OpenReadStream()).Returns(expectedStream.Object);
string validTempPath = string.Format(CultureInfo.InvariantCulture, @"{0}{1}.txt", Path.GetTempPath(), Guid.NewGuid());
var posted = new HttpPostedFile(file.Object);

//Act
posted.SaveAs(validTempPath);

//Assert
Assert.True(File.Exists(validTempPath), "Temp file should be created");

//Cleanup
File.Delete(validTempPath);
}
}