Tushar T.
Tushar T.

Reputation: 345

Issue with file upload in Web API 2 other then html form post

Issue with file upload in Web API 2

While i upload file with form post this work file but while i am sending same information from Rest Client like Postman in Google Chrome or posting file information with Android or iOS application Web Api 2 code is not detecting file multipart/form-post

Following is my html code

    <form enctype="multipart/form-data" method="post" action="/api/feedback">
    <input type="text" name="Scope" placeholder="Scope" value="feedback">
    <input type="text" name="Lang" placeholder="Lang" value="en">
    <input type="text" name="Collection" placeholder="Collection" value="7b22437573746f6d65724964223a392c2253657276696365526571756573744964223a312c224174746974756465223a332e322c22576f726b457468696373223a342e322c2248796769656e65223a352c22416d6f757450616964223a333132332e327d">
    <input type="file" name="Photo1" placeholder="Photo1">
    <input type="file" name="Photo2" placeholder="Photo2">
    <input type="file" name="Signature" placeholder="Signature">
    <input type="submit" value="Submit">
</form>

This .Net Web Api 2 Code

        public async Task<Result> Post()
    {
        var model = new ApiData();
        var result = new Result();
        if (Request.Content.IsMimeMultipartContent())
        {
            try
            {
                string root = HttpContext.Current.Server.MapPath("~/assets/temp");
                var provider = new MultipartFormDataStreamProvider(root);

                var sb = new System.Text.StringBuilder(); // Holds the response body
                // Read the form data and return an async task.
                await Request.Content.ReadAsMultipartAsync(provider);
                // This illustrates how to get the form data.
                foreach (var key in provider.FormData.AllKeys)
                {
                    foreach (var val in provider.FormData.GetValues(key))
                    {
                        if (key.Equals("Scope"))
                            model.Scope = val;
                        if (key.Equals("Lang"))
                            model.Lang = val;
                        if (key.Equals("Collection"))
                            model.Collection = val;
                    }

                }
                if (!model.Scope.Equals("feedback", StringComparison.InvariantCultureIgnoreCase))
                    result.Text = "Missing Scope.";
                else
                {
                    var Util = new Utils();
                    model.Collection = Util.ToString(model.Collection);
                    var _Feedback = JsonConvert.DeserializeObject<Feedback>(model.Collection);
                    try
                    {
                        // This illustrates how to get the file names for uploaded files.
                        foreach (var file in provider.FileData)
                        {
                            FileInfo fileInfo = new FileInfo(file.LocalFileName);
                            string BaseUrl = HttpContext.Current.Server.MapPath("~/assets/feedback/");
                            string oldFile = file.Headers.ContentDisposition.FileName.TrimStart('"').TrimEnd('"');
                            string NewName = string.Format("{0}{1}", Util.NewGuid, Path.GetExtension(oldFile));
                            if (file.Headers.ContentDisposition.Name.ToLower().Contains("photo"))
                            {
                                _Feedback.Photos = string.IsNullOrEmpty(_Feedback.Photos) ? NewName : _Feedback.Photos + "," + NewName;
                                fileInfo.MoveTo(BaseUrl + NewName);
                            }
                            else if (string.IsNullOrEmpty(_Feedback.Signatures) && file.Headers.ContentDisposition.Name.ToLower().Contains("signature"))
                            {
                                _Feedback.Signatures = NewName;
                                fileInfo.MoveTo(BaseUrl + NewName);
                            }
                        }
                    }
                    catch { }

                    if (Util.IsRequired(_Feedback.CustomerId)
                            && Util.IsRequired(_Feedback.ServiceRequestId)
                            && Util.IsRequired(_Feedback.Attitude)
                            && Util.IsRequired(_Feedback.WorkEthics)
                            && Util.IsRequired(_Feedback.Hygiene)
                            )
                    {
                        var feedback = new Feedback()
                        {
                            CustomerId = _Feedback.CustomerId,
                            ServiceRequestId = _Feedback.ServiceRequestId,
                            Attitude = _Feedback.Attitude,
                            WorkEthics = _Feedback.WorkEthics,
                            Hygiene = _Feedback.Hygiene,
                            AmoutPaid = _Feedback.AmoutPaid,
                            Photos = _Feedback.Photos,
                            Signatures = _Feedback.Signatures,
                            Created = DateTime.UtcNow,
                            Updated = DateTime.UtcNow
                        };

                        db.Feedbacks.Add(feedback);
                        db.SaveChanges();
                        if (feedback.Id != default(int))
                        {
                            result.Success = true;
                            result.Text = "Success";
                        }
                    }
                    else
                    {
                        result.Text = "Required Parameters missing.";
                    }
                }
            }
            catch
            {
                result.Text = "Error";
            }
        }
        else
            result.Text = "Signature or photo missing";
        return result;
    }

This is Postmen request

enter image description here

Exposing post request in Fiddler Client i have seen that while posting using html form post there is boundary in multipart/form-data; although there is no boundary in Postman or other RestClient.

Upvotes: 1

Views: 3308

Answers (2)

Ziphozonke Shongwe
Ziphozonke Shongwe

Reputation: 11

I know this an old post but I think this could help someone who has the same issue. In postman remove Content-Type header. The request will go through fine.

Upvotes: 1

ManOVision
ManOVision

Reputation: 1893

This may be a Postman bug.

To summarize, if you set the Content-Type header with Postman, it seems to override the default browser functionality and not add the boundary. Most the time this is a good thing, but not for multipart/form-data since we need the browser to add the boundary for us. Try removing the Content-Type header. When sending the actual Post, the browser will automatically add the proper header and create the boundary.

Your WebApi code looks fine. Your if check will just be false.

//This will be false since it's a malformed request.
if (Request.Content.IsMimeMultipartContent())

Upvotes: 5

Related Questions