ASP. NET Web API File upload

Source: Internet
Author: User

1 The right procedure

 Public classAvatercontroller:baseapicontroller{[httppost] Public AsyncTask<ihttpactionresult> Uploadavater (intuserId) {AVATARBLL PICTUREBLL=NewAVATARBLL ( This.            Request); awaitPicturebll.uploadavatar (userId); returnOk (); }//Other Action} Public classavatarbll{Privatehttprequestmessage httprequestmessage; PublicAVATARBLL (Httprequestmessage httprequestmessage) { This. Httprequestmessage =httprequestmessage;} Public AsyncTask Uploadavatar (intuserId) {            if(! HttpRequestMessage.Content.IsMimeMultipartContent ("Form-data"))            {                //Throw Exception            }//get the data that the client passes to the serverlist<byte> list =Newlist<byte>(); awaitHttpRequestMessage.Content.ReadAsMultipartAsync (). ContinueWith (multipartcontent =             {                if(multipartcontent.isfaulted | |multipartcontent.iscanceled) {//Throw Exception                }                foreach(varContentinchmultipartContent.Result.Contents) {varb =content. Readasbytearrayasync ().                    Result; List.                AddRange (b); }         });//other parts (storing data in MongoDB and other business logic)}}

2 Wrong procedure

 Public classAvatercontroller:baseapicontroller{[httppost] PublicIhttpactionresult Uploadavater (intuserId) {AVATARBLL PICTUREBLL=NewAVATARBLL ( This.            Request);            Picturebll.uploadavatar (USERID); returnOk (); }//Other Action} Public classavatarbll{Privatehttprequestmessage httprequestmessage; PublicAVATARBLL (Httprequestmessage httprequestmessage) { This. Httprequestmessage =httprequestmessage;} Public voidUploadavatar (intuserId) {            if(! HttpRequestMessage.Content.IsMimeMultipartContent ("Form-data"))            {                //Throw Exception            }//get the data that the client passes to the serverlist<byte> list =Newlist<byte>(); MemoryStream Ms=NewMemoryStream (); Try{Multipartmemorystreamprovider Mmsp=NewMultipartmemorystreamprovider (); varTask = httprequestmessage.content.readasmultipartasync<multipartmemorystreamprovider> (Mmsp,100000); Task.                 Wait (); varContents =task.                 result.contents; foreach(varCinchcontents) {                    varb =C.readasbytearrayasync ();                    B.wait (); List.                 AddRange (B.result); }              }              Catch(AggregateException ex) {}//other parts (storing data in MongoDB and other business logic)}}

3 Error Phenomena:

In the second way, if the amount of data that the client uploads to the service (calling Uploadavater uploaded Data ) is less than the size of the buffer set by the server, then the file can be uploaded normally, if it is larger than the size of the buffer set by the server, it will not be uploaded properly. Debug the server-side code when executing to a task. Wait (); when this line of statements occurs, the client waits until the client call times out and never returns the call result, and a deadlock has occurred!!! Use httprequestmessage.content.readasmultipartasync<multipartmemorystreamprovider> (MMSP, 1000); set the buffer size to 1000bit. This method has several overloaded methods, one of which is to not display the set buffer size, then the buffer size is the default.

4 Error point analysis for the second method:

See WEB API DLL settings in the source code:

can see the default The buffer area size is 32*1024, that is, 32K, then upload more than 32k without setting the buffer size, why a deadlock occurs, and the buffer setting exceeds the size of the upload file why does the deadlock occur? The possibility of a deadlock occurs regardless of whether the buffer size is set sufficiently large.

The main method is shown in the method body with the following code:

The core approach to this code:

The above method iterates through the request data, and when the buffer size is set less than the amount of data that the client sends to the server, it is necessary to iterate through the data several times, and each time the data is read, it calls two async methods:

However, The return value of the Readasmultipartasync method is task<t>(T is streamprovider), so when calling the Task.wait () method Waits,the Readasmultipartasync method also waits for asynchronous processing Streamprovider to return results, which creates a deadlock.

5 First Method Why is there no deadlock?

The first method uses awaitto implement the synchronization mechanism without invoking the task.wait () method, thus avoiding a,B The possibility that two blocks of code will wait for the result to return and cause a deadlock.

ASP. NET Web API File upload

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.