Search code examples
asp.net-mvc-4asp.net-web-apihttp-postwindows-phone-8.1http-put

Sending Multipart form data from windows phone to web api


Hi I want to send(post/put) some data(containing string, int and Stream) from windows phone 8.1 using HttpClient to web api. what is the best way to do that.

 public async void Put(string uri)
    {
        var httpClient = new System.Net.Http.HttpClient();

        MultipartFormDataContent content = new MultipartFormDataContent();
        var stringContent = new StringContent("FirstName=MUH&LastName=Test", Encoding.UTF8, "multipart/form-data");
        var test = new StreamContent(new MemoryStream());
        content.Add(test);
        content.Add(stringContent);
        var message = await httpClient.PutAsync(url+"/UpdateTest", content);

        message.EnsureSuccessStatusCode();

        string content1 = await message.Content.ReadAsStringAsync();

    }

api method in my mvc app

 [AllowAnonymous]
    [Route("~/api/account/UpdateTest")]
    [HttpPut]
    public async Task<object> UpdateTest()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }
        try
        {
            var requestParts = await Request.Content.ReadAsMultipartAsync();
            foreach (var part in requestParts.Contents)
            {
                //part is always StreamContent
                var test = await part.ReadAsStreamAsync();
                var test1 = await part.ReadAsStringAsync();
            }
        }
        catch (Exception ex)
        { }
    }

In my windows phone project I have passed 2 HttpContent, one is StreamContent where as other is StringContent. but in my web api put method both are StreamContent I do't know why.

and other problem is I have to parse the string key value in StingContnet. My question is what is the best way of sending/receiving multipart form data from windows phone 8.1 to web api,

Thanks


Solution

  • Following is an example(change this accordingly to your scenario):

    HttpClient client = new HttpClient();
    client.BaseAddress = new Uri(baseAddress);
    
    HttpRequestMessage request = new HttpRequestMessage();
    
    MultipartFormDataContent mfdc = new MultipartFormDataContent();
    mfdc.Add(new StringContent("Michael"), name: "FirstName");
    mfdc.Add(new StringContent("Jordan"), name: "LastName");
    mfdc.Add(new StreamContent(content: new MemoryStream(Encoding.UTF8.GetBytes("This is from a file"))), 
            name: "Data", 
            fileName: "File1.txt");
    
    HttpResponseMessage response = await client.PostAsync(baseAddress + "/api/values", mfdc);
    

    public async Task Post()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.BadRequest);
        }
    
        MultipartFormDataStreamProvider prov = await Request.Content.ReadAsMultipartAsync<MultipartFormDataStreamProvider>(new MultipartFormDataStreamProvider(@"C:\uploadedfiles"));
    
        // example of how you can read the form data
        string firstName = prov.FormData["FirstName"];
    
        // Get list of all files that have been uploaded and stored in the above provided root folder 
        Collection<MultipartFileData> files = prov.FileData;
    }
    

    Following is how request looks like in Fiddler tool:

    POST http://localhost:9095/api/values HTTP/1.1
    Content-Type: multipart/form-data; boundary="7560a854-a71a-4e55-9571-5c2de520f45f"
    Host: kirandesktop:9095
    Content-Length: 474
    Expect: 100-continue
    Connection: Keep-Alive
    
    --7560a854-a71a-4e55-9571-5c2de520f45f
    Content-Type: text/plain; charset=utf-8
    Content-Disposition: form-data; name=FirstName
    
    Michael
    --7560a854-a71a-4e55-9571-5c2de520f45f
    Content-Type: text/plain; charset=utf-8
    Content-Disposition: form-data; name=LastName
    
    Jordan
    --7560a854-a71a-4e55-9571-5c2de520f45f
    Content-Disposition: form-data; name=Data; filename=File1.txt; filename*=utf-8''File1.txt
    
    This is from a file
    --7560a854-a71a-4e55-9571-5c2de520f45f--
    

    Also note that you can read the StreamContent anyway you want...in the following examples, I am simulating a request's body stream and reading it as a simple string or deserializing into an object of type Person.

    StreamContent requestStream = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes("Hello World!")));
    string data = await requestStream.ReadAsStringAsync();
    
    //---------------------
    
    StreamContent requestStream = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes("{ \"FirstName\" : \"Michael\" }")));
    requestStream.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    Person person = await requestStream.ReadAsAsync<Person>();