Api service code 1:
/// <summary> /// Server receiving interface /// </summary> [HttpPost] [Route("ReceiveFile")] public HttpResponseMessage ReceiveFile() { string result = string.Empty; ArrayList list = new ArrayList(); try { Stream postStream = HttpContext.Current.Request.InputStream; byte[] b = new byte[postStream.Length]; string postFileName = DNTRequest.GetString("fileName"); if (string.IsNullOrEmpty(postFileName) && HttpContext.Current.Request["fileName"] != null) { postFileName = HttpContext.Current.Request["fileName"]; } string fileExtension = Path.GetExtension(postFileName); string dirName = "other"; if (!string.IsNullOrEmpty(fileExtension)) { dirName = fileExtension.Substring(fileExtension.LastIndexOf(".") + 1); } string dir = "/_temp/file/" + dirName + "/" + DateTime.Now.ToString("yyyyMMdd") + "/"; string fileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff"); fileName += fileExtension; string filePath = HttpContext.Current.Server.MapPath(dir); string saveFilePath = Path.Combine(filePath, fileName); string dirPath = dir + fileName; list.Add(dirPath); if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } FileStream fs = new FileStream(saveFilePath, FileMode.Create); byte[] new_b = new byte[1024]; const int rbuffer = 1024; while (postStream.Read(new_b, 0, rbuffer) != 0) { fs.Write(new_b, 0, rbuffer); } postStream.Close(); fs.Close(); fs.Dispose(); if (list.Count > 0) { result = DNTRequest.GetResultJson(true, "success", string.Join(",", list.ToArray())); } } catch (Exception ex) { result = DNTRequest.GetResultJson(false, ex.Message, null); } HttpResponseMessage responseMessage = new HttpResponseMessage { Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "text/plain") }; return responseMessage; }
Api service code 2:
[HttpPost] [Route("ReceiveFileTest")] public HttpResponseMessage ReceiveFileTest() { string result = string.Empty; var request = HttpContext.Current.Request; try { if (request.Files.Count > 0) { var fileNameList = new List<string>(); string dirName = "other"; foreach (string f in request.Files) { var file = request.Files[f]; string fileExtension = Path.GetExtension(file.FileName).ToLower(); string fileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff"); fileName += fileExtension; if (!string.IsNullOrEmpty(fileExtension)) { dirName = fileExtension.Substring(fileExtension.LastIndexOf(".") + 1); } string dir = "/_temp/file/" + dirName + "/" + DateTime.Now.ToString("yyyyMMdd") + "/"; string filePath = HttpContext.Current.Server.MapPath(dir); if (!Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } string fileSavePath = Path.Combine(filePath, fileName); Stream postStream = file.InputStream; // FileStream fs = new FileStream(fileSavePath, FileMode.Create); byte[] new_b = new byte[1024]; const int rbuffer = 1024; while (postStream.Read(new_b, 0, rbuffer) != 0) { fs.Write(new_b, 0, rbuffer); } postStream.Close(); fs.Close(); fs.Dispose(); string dirPath = dir + fileName; fileNameList.Add(dirPath); fileNameList.Add(fileName); } result = DNTRequest.GetResultJson(true, string.Format("{0}:{1}", HttpStatusCode.OK, string.Join(",", fileNameList.ToArray())), null); } else { result = DNTRequest.GetResultJson(false, "Please select the uploaded file", null); } } catch (Exception ex) { result = DNTRequest.GetResultJson(false, ex.Message, null); } HttpResponseMessage responseMessage = new HttpResponseMessage { Content = new StringContent(result, Encoding.GetEncoding("UTF-8"), "text/plain") }; return responseMessage; }
Ajax submits the file code and calls the Script of Api code 1:
In Api code 1 on the back end of this method, the file name cannot be obtained all the time, so I added "fileName=fileObj.name" to the Ajax url, so that debugging can go through. I'm still working on why Ajax can't get the filename when it's submitted.
<script> $("#inpSubmit").click(function () { //var fileObj = new FormData($("#importModel")[0]); var fileObj = document.getElementById("inpFileControl").files[0]; if (typeof (fileObj) == "undefined" || fileObj.size <= 0) { alert("please select file"); return; } //console.log(fileObj); var formFile = new FormData(); formFile.append("fileName", fileObj.name); formFile.append("file", fileObj); //console.log(JSON.stringify(formFile)); //var paramters = {}; //paramters.timestamp = new Date().getTime(); //paramters.fileName = fileObj.name; //paramters.file = fileObj; //console.log(JSON.stringify(paramters)); $.ajax({ type: "post", url: "http://localhost:19420/Api/ReceiveFile?fileName=" + fileObj.name, dataType: "json", //contentType: false, processData: false, / / used to serialize data parameters. The default value is true. By default, the data sent will be converted to objects. If you do not want to convert the File, you need to set it to false cache: false, data: fileObj, success: function (json) { if (json.result) { $("#inpFileUrl").val(json.data); console.log(json.data); } else { alert(json.msg); } }, error: function (ret) { console.log(ret.responseText); } }); return false; }); </script>
Ajax submits file code and calls Html of Api code 1:
<form> <fieldset> <legend>Ajax Commit to remote server Api</legend> <div class="form-group"> <label class="col-sm-2 control-label" for="ds_host">Select file</label> <div class="col-sm-4"> <input class="form-control" id="inpFileUrl" name="inpFileUrl" type="text" placeholder="Return address after upload" /> </div> <div class="col-sm-4"> <input type="file" id="inpFileControl" name="file" /> </div> <div class="col-sm-2"> <input id="inpSubmit" name="inpSubmit" type="button" value="Submission" /> </div> </div> </fieldset> </form>
The Form form is submitted to Post in remote Api code 2, which is very smooth. Html below
<form action="http://localhost:19420/Api/ReceiveFileTest" method="post" enctype="multipart/form-data"> <fieldset> <legend>Form Submit form to remote server Api</legend> <div class="form-group"> <label class="col-sm-2 control-label" for="ds_host">Select file</label> <div class="col-sm-4"> <input class="form-control" id="inpFileUrl2" name="inpFileUrl2" type="text" placeholder="Return address after upload" /> </div> <div class="col-sm-4"> <input type="file" name="file" /> </div> <div class="col-sm-2"> <input type="submit" value="Submission" /> </div> </div> </fieldset> </form>
When deploying the Api service, you need to consider the cross domain problem when the client submits the file. The shortcut is to set access control allow origin: * in IIS, but there is a security problem.
The upload file size of the website is 4M by default, so it needs to be set in the website configuration file, as follows:
<system.web> <httpRuntime maxRequestLength="409600" /> </system.web>
There is also a limit on the size of files uploaded by server IIS, which should also be set as follows:
<system.webServer> <security> <requestFiltering> <!--2G/2072576000|500M/518144000--> <requestLimits maxAllowedContentLength="518144000"/> </requestFiltering> </security> </system.webServer>
These are my research results in the past two days, which need to be improved if not perfect.
The tripartite framework RestSharp is used in Api. Please find NuGet to add it in the solution.
The external operation class uses the following methods: 1
/// <summary> /// Assemble JSON /// </summary> static public string GetResultJson(bool result, string msg, Object data) { string resultJson = string.Empty; Hashtable ht = new Hashtable(); try { ht.Add("result", result); ht.Add("msg", msg); ht.Add("data", data); } catch (Exception ex) { ht.Add("result", false); ht.Add("msg", ex.Message); } resultJson = Newtonsoft.Json.JsonConvert.SerializeObject(ht); return resultJson; }
Note: the file control in Html code needs to have the name = "file" attribute, otherwise Api cannot get the file object after submitting, as follows.
<input type="file" name="file" />
The third method is to submit the form form and call the control of mvc. Control is calling Api code 2. This test failed and the file can be uploaded, but the uploaded file cannot be opened is damaged. We are trying to solve this problem.
Below is the Html code for the third method:
<form action="/Test/UploadFileTest" method="post" enctype="multipart/form-data"> <fieldset> <legend>Form Submit form to local Control</legend> <div class="form-group"> <label class="col-sm-2 control-label" for="ds_host">Select file</label> <div class="col-sm-4"> <input class="form-control" id="inpFileUrl3" name="inpFileUrl3" type="text" placeholder="Return address after upload" /> </div> <div class="col-sm-4"> <input type="file" name="file" /> </div> <div class="col-sm-2"> <input type="submit" value="Submission" /> </div> </div> </fieldset> </form>
Below is the Control code for the third method:
[HttpPost] public ActionResult UploadFileTest() { string result = string.Empty; string apiUrl = "http://localhost:19420/Api/ReceiveFileTest"; string contentType = "application/octet-stream"; var files = new List<string>(); foreach (string f in Request.Files) { var file = Request.Files[f]; var request = new RestRequest(Method.POST); request.AlwaysMultipartFormData = true; //request.AddParameter("fileName", file.FileName); Stream postStream = file.InputStream; byte[] b = new byte[postStream.Length]; request.AddFile("file", b, file.FileName, contentType); var restClient = new RestClient { BaseUrl = new Uri(apiUrl) }; string res = string.Empty; IRestResponse<Object> response = restClient.Execute<Object>(request); if (response.StatusCode == HttpStatusCode.OK) { res = response.Content; } else { res = string.Format("{0}:{1}", response.StatusCode, response.Content); } files.Add(res); } if (files.Count > 0) { result = string.Join(",", files.ToArray()); } return Json(result); }