0

I am using Asp net web form 4.5.1 and Asp net web Api and I trying to send some data and file to Web Api method, my code is based on [http://www.asp.net/web-api/overview/working-with-http/sending-html-form-data,-part-2][1] example but I want to send data via AJAX (jquery)

var formData = new FormData();
                var opmlFile = $('#packFile')[0];
                formData.append("opmlFile", opmlFile.files[0]);
                formData.append("packageData",  JSON.stringify(ko.mapping.toJS(this.selectedItem)));

                $.ajax({
                    type: "POST",
                    url: "/api/MyController/MyMethod",                   
                    dataType: "json",
                    data: formData,
                    cache: false,
                    contentType: false,
                    processData: false,
                    success: function (response) {

                    },
                    failure: function (response) {

                    }
                });

it seems like working case, but if I send file with in request my object data is not available(provider.FormData.AllKeys ). How to make it works ? of course I can send 2 request but it is seems not good for me.

public async Task<HttpResponseMessage> MyMethod()
    {
        // Check if the request contains multipart/form-data.
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }

        string root = HttpContext.Current.Server.MapPath("~/App_Data");
        var provider = new MultipartFormDataStreamProvider(root);

        // Read the form data and return an async task.
        var task = Request.Content.ReadAsMultipartAsync(provider).
            ContinueWith<HttpResponseMessage>(t =>
            {
                if (t.IsFaulted || t.IsCanceled)
                {
                    Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);
                }

                // This illustrates how to get the file names.
                foreach (MultipartFileData file in provider.FileData)
                {
                    Trace.WriteLine(file.Headers.ContentDisposition.FileName);
                    Trace.WriteLine("Server file path: " + file.LocalFileName);
                }

                foreach (var key in provider.FormData.AllKeys)
                {
                    foreach (var val in provider.FormData.GetValues(key))
                    {
                        Trace.WriteLine(string.Format("{0}: {1}", key, val));
                    }
                }

                return Request.CreateResponse(HttpStatusCode.OK);
            });

        return await task;

    }

1 Answer 1

2

Here your multipart request is having JSON + file data, where as MultipartFormDataStreamProvider expects form data + file...an example of how a typical multipart formdata request looks like...notice the header called Content-Disposition: form-data...

POST http://localhost:50460/api/values/1 HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------41184676334
Content-Length: 29278

-----------------------------41184676334
Content-Disposition: form-data; name="caption"

Summer vacation
-----------------------------41184676334
Content-Disposition: form-data; name="image1"; filename="GrandCanyon.jpg"
Content-Type: image/jpeg

(Binary data not shown)
-----------------------------41184676334--

For your scenario, you can either create a custom multipart stream provider deriving from the abstract MultipartStreamProvider or you can do something like below:

Customer customer = null;
foreach(HttpContent content in provider.Contents)
{
    if(content.Headers.ContentType.MediaType == "application/json")
    {
        customer = await content.ReadAsAsync<Customer>();
        break;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.