ASP. NET WebAPi (selfhost) implements synchronous or asynchronous file upload,

Source: Internet
Author: User
Tags baseuri net serialization

ASP. NET WebAPi (selfhost) implements synchronous or asynchronous file upload,

Preface
We have discussed how to use AngularJs to upload files to WebAPi for processing. We also talked about file upload in the MVC series. This article uses MVC + WebAPi for synchronous or asynchronous file upload, by the way, we will review css, js, and MVC as the client, while WebAPi uses the selfhost mode that does not depend on IIS as the server to receive client files and use Ajax to implement the process, let's take a look.

Synchronous upload

Let's look at the page.

<Div class = "container"> <div> @ if (ViewBag. Success! = Null) {<div class = "alert-danger" role = "alert"> <strong> success! </Strong> upload successfully. <a href = "@ ViewBag. success "target =" _ blank "> open file </a> </div>} else if (ViewBag. failed! = Null) {<div class = "alert-danger" role = "alert"> <strong> failed! </Strong> @ ViewBag. failed </div >}</div> @ using (Html. beginForm ("SyncUpload", "Home", FormMethod. post, new {role = "form", enctype = "multipart/form-data", @ style = "margin-top: 50px ;"})) {<div class = "form-group"> <input type = "file" id = "file" name = "file"/> </div> <input type = "submit "value =" Submit "class =" btn-primary "/>}</div>

After direct upload, we can view the path of the uploaded file and access it through the upload status, which is so simple. The following is the MVC background logic.

[HttpPost] public ActionResult SyncUpload (HttpPostedFileBase file) {using (var client = new HttpClient () {using (var content = new MultipartFormDataContent ()) {byte [] Bytes = new byte [file. inputStream. length + 1]; file. inputStream. read (Bytes, 0, Bytes. length); var fileContent = new ByteArrayContent (Bytes); // set the attachment in the Request Header as the file name for obtaining fileContent in WebAPi. headers. contentDisposition = new System. net. http. headers. contentDispositionHeaderValue ("attachment") {FileName = file. fileName}; content. add (fileContent); var requestUri =" http://localhost:8084/api/upload/post "; Var result = client. postAsync (requestUri, content ). result; if (result. statusCode = System. net. httpStatusCode. created) {// obtain the address of the uploaded file and render it to the view to access var m = result. content. readAsStringAsync (). result; var list = JsonConvert. deserializeObject <List <string> (m); ViewBag. success = list. firstOrDefault ();} else {ViewBag. failed = "Upload Failed, Status Code:" + result. statusCode + ", reason:" + result. reasonPhrase + ", error message:" + result. content. toString () ;}} return View ();}

Note:The above will be obtained to the file byte stream array needs to be passed to MultipartFormDataContent, otherwise the file data will not be obtained when passed to WebAPi.

So far, the operations in MVC have been completed. Now let's look at what operations need to be done in WebAPi.

(1) first, you must determine whether the uploaded data is of the MimeType type.

 if (!Request.Content.IsMimeMultipartContent()) {  throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); }

(2) We must re-generate a file name to avoid duplication, using Guid, Date, or other.

 string name = item.Headers.ContentDisposition.FileName.Replace("\"", ""); string newFileName = Guid.NewGuid().ToString("N") + Path.GetExtension(name);

(3) We need to use this class of MultipartFileStreamProvider to set the upload path and write the file into it.

 var provider = new MultipartFileStreamProvider(rootPath); var task = Request.Content.ReadAsMultipartAsync(provider).....

(4) return the Upload File address.

Return Request. CreateResponse (HttpStatusCode. Created, JsonConvert. SerializeObject (savedFilePath ));
The Assembly Code is as follows:

Public Task <HttpResponseMessage> Post () {List <string> savedFilePath = new List <string> (); if (! Request. content. isMimeMultipartContent () {throw new HttpResponseException (HttpStatusCode. unsupportedMediaType);} var substringBin = AppDomain. currentDomain. baseDirectory. indexOf ("bin"); var path = AppDomain. currentDomain. baseDirectory. substring (0, substringBin); string rootPath = path + "upload"; var provider = new MultipartFileStreamProvider (rootPath); var task = Request. content. readAsMultipartAsync (provider ). continueWith <HttpResponseMessage> (t => {if (t. isCanceled | t. isFaulted) {Request. createErrorResponse (HttpStatusCode. internalServerError, t. exception);} foreach (MultipartFileData item in provider. fileData) {try {string name = item. headers. contentDisposition. fileName. replace ("\" "," "); string newFileName = Guid. newGuid (). toString ("N") + Path. getExtension (name); File. move (item. localFileName, Path. combine (rootPath, newFileName); // Request. requestUri. pathAndQury is the address after the domain name to be removed // if the above request is http://localhost:80824/api/upload/post This parameter is set to api/upload/post // Request. RequestUri. AbsoluteUri. http://localhost:8084/api/upload/post Uri baseuri = new Uri (Request. requestUri. absoluteUri. replace (Request. requestUri. pathAndQuery, string. empty); string fileRelativePath = rootPath + "\" + newFileName; Uri fileFullPath = new Uri (baseuri, fileRelativePath); savedFilePath. add (fileFullPath. toString ();} catch (Exception ex) {string message = ex. message;} return Request. createResponse (HttpStatusCode. created, JsonConvert. serializeObject (savedFilePath);}); return task ;}

Note: The preceding item. localFileName is E: \ Documents \ Visual Studio 2013 \ Projects \ WebAPiReturnHtml \ upload \ BodyPart_fa01ff79-4a5b-40f6-887f-ab514ec6636f, because at this time we renamed the file name, so we need to move the file to the file address that we renamed.

The whole process is so simple. Let's take a look at the demonstration results.

At this time, an error occurred. It is a bit intriguing. on the server side, the following Json string is returned.

Copy codeThe Code is as follows: List <string> savedFilePath = new List <string> ();

In this case, an error occurs during deserialization. Let's take a look at the error message on the page:

The string cannot be converted to List <string>. Isn't this a one-to-one correspondence? Well, let's see what the returned string is like, when you move the mouse up, you can see the following:

[Click to view]The result is as follows:

The result returned by clicking the View button is the correct json. NET serialization is also problematic, so during deserialization, the returned string needs to be converted to the correct json string for deserialization. The modification is as follows:

  var m = result.Content.ReadAsStringAsync().Result;      m = m.TrimStart('\"');      m = m.TrimEnd('\"');      m = m.Replace("\\", "");      var list = JsonConvert.DeserializeObject<List<string>>(m);

The page is displayed as follows:

At this point, our synchronous upload has come to an end, where Json is used. NET encountered an error during deserialization. Json. NET deserialization is a strange and confusing problem.

Asynchronous upload

The so-called asynchronous upload only uses Ajax for upload. This is to review the script or Razor view. The following content only modifies the view. For Asynchronous upload, I used jquery. form. for the asynchronous api in js, see the following code:

<Script src = "~ /Scripts/jquery-1.10.2.min.js "> </script> <script src = "~ /Scripts/jquery. form. js "> </script> <script src = "~ /Scripts/bootstrap. min. js "> </script> <link href = "~ /Content/bootstrap.min.css "rel =" stylesheet "/> <div class =" container "style =" margin-top: 30px "> <div id =" success "style =" display: none; "> <div class =" alert-danger "role =" alert "> <strong> upload successful </strong> <span style =" margin-right: 50px; "> </span> <a href =" "target =" _ blank "id =" linkAddr "> file access address </a> </div> <div id = "fail" style = "display: none; "> <div class =" alert-danger "role =" alert "> <strong> Upload Failed </strong> </div> @ using (Ajax. beginForm ("AsyncUpload", "Home", new AjaxOptions () {HttpMethod = "POST"}, new {enctype = "multipart/form-data ", @ style = "margin-top: 10px ;"})) {<div class = "form-group"> <input type = "file" name = "file" id = "fu1"/> </div> <div class = "form -group "> <input type =" submit "class =" btn-primary "value =" Upload "/> </div >}< div class =" form-group"> <div class = "progre Ss "id =" progress "style =" display: none; & quot;> <div class = "progress-bar"> 0% </div> <div id = "status"> </div> <style>. progress {position: relative; width: 400px; border: 1px solid # ddd; padding: 1px ;}. progress-bar {width: 0px; height: 40px; background-color: #57be65 ;}</style> <script> (function () {var bar =$ ('. SS-bar '); var percent = $ ('. SS-bar '); $ ('form '). ajaxForm ({beforeS End: function () {$ ("# progress "). show (); var percentValue = '0% '; bar. width (percentValue); percent.html (percentValue) ;}, uploadProgress: function (event, position, total, percentComplete) {var percentValue = percentComplete + '%'; bar. width (percentValue); percent.html (percentValue) ;}, success: function (d) {var percentValue = '000000'; bar. width (percentValue); percent.html (percentValue); $ ('# fu 1 '). val ('') ;}, complete: function (xhr) {if (xhr. responseText! = Null) {$ ("# linkAddr "). prop ("href", xhr. responseText); $ ("# success "). show ();} else {$ ("# fail "). show () ;}}) ;}) (); </script>

Let's take a look at the upload process.

Uploading:

Upload completed:

Of course, 100% is just a real-time upload of small files. If it is a large file, it is certainly not real-time. It is more suitable to use other components. Here I just want to learn more.

Note:Here we need to re-apply it. previously described in the MVC upload, the default MVC File Upload is limited, so if it exceeds the limit, it cannot be uploaded. You need to make the following settings:

(1) In IIS 5 and IIS 6, the maximum size of files to be uploaded is 4 MB by default. When the size of the uploaded files exceeds 4 MB, an error message is displayed, however, we can set the file size as shown in the following figure.

<system.web> 

(2) In IIS 7 +, the maximum size of the default file to be uploaded is 28.6 mb. When the default size is exceeded, an error message is also displayed, however, you can set the file upload size (as shown in the following figure ).

<system.webServer> <security>  <requestFiltering>   <requestLimits maxAllowedContentLength="2147483647" />  </requestFiltering> </security></system.webServer>

Summary

In this section, we learned how to isolate MVC and WebAPi for upload. At the same time, we also found that Json is used in deserialization. NET, we hereby record that when one-to-one response is found, the Json string returned by deserialization is not a standard Json string, we need to process the returned Json string as follows (maybe there are other solutions ).

Var jsonString = "Returned json string"; jsonString = jsonString. trimStart ('\ "'); jsonString = jsonString. trimEnd ('\ "'); jsonString = jsonString. replace ("\\","");

Next, we will prepare the system to learn about SQL Server and Oracle, step by step! Rest, rest!

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Related Article

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.