Jonathan Hansen
Jonathan Hansen

Reputation: 443

HttpContext.Current.Request.Files is always empty

I see lots of examples of WebAPIs accepting files. However, I have yet to find a solution as to why, no matter what I've tried, to get my HttpContext.Current.Request.Files to ever have a file in it that I am posting to the Web API through Postman. (I have also posted that image through a Console Application and got the same result)

[HttpPost]
[ActionName("Post")]
[ResponseType(typeof(PeliquinApiRsp))]
    public IHttpActionResult Post(int personId)
    {
        var empPicture = PeliquinIOC.Resolve<IEmpPictureBL>(UserId, UserName, PropertyCode);

        if (!(IsAllowed(SysPrivConstants.SYSPRIV__TYPE_PERSONNEL, SysPrivConstants.SYSPRIV__FUNC_PERSONNEL_CARDHOLDER, SysPrivConstants.SYSPRIV__LEVEL_FULL)))
            return (Unauthorized());

        var apiRsp = new PeliquinApiRsp();

        var httpRequest = HttpContext.Current.Request;

        if (httpRequest.Files.Count == 0)
        return BadRequest();

        empPicture.Post(httpRequest.Files[0].InputStream, personId);

        apiRsp.SetStatus();
        apiRsp.SetData("EmpPicture");

        return (Ok(apiRsp));
    }

It is a very simple method. I've been using Postman to post a Binary .jpg file. I have set the content-type = "multipart/form-data". No error is throw in my code, other than the .Files = 0.

I have some additional settings in my WebApiConfig for the rest of the API, but I'll include them just in case, along with the route for this particular method:

config.Formatters.Remove( config.Formatters.XmlFormatter );
config.Formatters.JsonFormatter.SupportedMediaTypes.Add( new MediaTypeHeaderValue( "application/json" ) );
config.Formatters.FormUrlEncodedFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));


config.Routes.MapHttpRoute(
            name: "EmpPicturePost",
            routeTemplate: "api/EmpPicture/{personId}",
            defaults: new { controller = "EmpPicture", action = "Post" },                
            constraints: new { personId = @"^\d+$", httpMethod = new HttpMethodConstraint(HttpMethod.Post, HttpMethod.Options) }
        );

I am at wit's end trying to figure out why something so simple, just doesn't work. I've tried quite a few other way of doing this, that were all more MVC-like, but this isn't an MVC app, and they threw different errors. Thanks for any help.

Upvotes: 3

Views: 8828

Answers (3)

Ivo Tabakov
Ivo Tabakov

Reputation: 11

I think Postman is not capable of filling the HttpContext.Current.Request.Files collection. We fixed the problem by using: await Request.Content.ReadAsByteArrayAsync().ConfigureAwait(false);

Ivo

Upvotes: 0

RBT
RBT

Reputation: 25945

I suspect in all likely hood the root cause of your problem is because of this what you've mentioned in your post -

I've been using Postman to post a Binary .jpg file. I have set the content-type = "multipart/form-data"

You should not be doing so explicitly in postman tool. Postman tool is smart enough to auto-detect Content-Type on its own. Please see this answer of mine to help you more with it.

Setting up Content-Type to "multipart/form-data" involves a complex concept of boundaries of multiple parts as detailed here. Heavy lifting of setting up the boundaries is done automatically for you by postman tool which is why it doesn't want you to set the content-type explicitly in this case.

Upvotes: 0

Neorcisa
Neorcisa

Reputation: 124

I also struggle with this issue for a while but eventually found a solution. In my case i was calling the endpoint from an iOS app and the files where always empty. I found that it I need to have a http header that matches the file field name in the form so the request would have to have an http header for example:

file: newImage.jpg

and inside the body of the request you would need something like

Content-Disposition: form-data; name="file"; filename="newImage.jpg"
Content-Type: image/jpg

Please be aware that this is not a valid request just a snippet. You still need more http headers and the boundaries around the fields in the body. My point is that it seem the requirement is that http header key and the form field name match and both exist.

Upvotes: 1

Related Questions