August 23, 2021

HttpPostedFile vs HttpPostedFileBase

While working with posted files in .Net MVC, you might have stuck with HttpPostedFileBase and HttpPostedFile. These classes have the same properties, but are not related. You can not cast one to the other, because they are completely different objects to .net.

HttpPostedFileBase is an abstract class, used solely for the purpose of being derived from. It is used to mock certain things in sealed class HttpPostedFile. To make things consistent, HttpPostedFileWrapper was created to convert HttpPostedFile to HttpPostedFileBase.

  • HttpPostedFile is a class representing posted files, its definitation looks like this:

    public sealed class HttpPostedFile
    

    This class can't be inherited and can't be mocked for unit testing.

  • HttpPostedFileBase is a unified abstraction, enables the developer to create mockable objects.

    public abstract class HttpPostedFileBase
    
  • HttpPostedFileWrapper is an implementation of HttpPostedFileBase that wraps HttpPostedFile. It looks like this:

    public class HttpPostedFileWrapper : HttpPostedFileBase
    {
    	public HttpPostedFileWrapper(HttpPostedFile httpPostedFile) 
    	{
    		//
    	};
    	//...
    

Create HttpPostedFileBase object from HttpPostedFile:

You can use HttpPostedFileWrapper class, which will accept HttpPostedFile object as a parameter to its constructor.

//suppose httpPostedFile is an object of HttpPostedFile class
HttpPostedFileWrapper httpPostedFileWrapper = new HttpPostedFileWrapper(httpPostedFile);
HttpPostedFileBase httpPostedFileBase = httpPostedFileWrapper; //HttpPostedFileBase is the parent class

Thanks to polymorphism, you can pass an instance of derived class (HttpPostedFileWrapper), to method accepting base class(HttpPostedFileBase)

Create HttpPostedFile object from HttpPostedFileBase:

Creating HttpPostedFile object is not straight similar as it is in above case. You have to make use of System.Reflection to achieve this:

var constructorInfo = typeof(HttpPostedFile).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0];
var httpPostedFile = (HttpPostedFile)constructorInfo
		  .Invoke(new object[] { httpPostedFileBase.FileName, httpPostedFileBase.ContentType, httpPostedFileBase.InputStream });

1 comment:

  1. getting this issue " System.ArgumentException: 'Object of type 'System.IO.MemoryStream' cannot be converted to type 'System.Web.HttpInputStream'.'"

    ReplyDelete