Reputation: 2788
I want to post a file to server asynchronously without posting the form. I have the following code:
var fileInput = document.getElementById('FileInput');
var file = fileInput.files[0];
var formData = new FormData();
formData.append('file', file, file.name);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://servername/controllername/AnalyseFile', true);
xhr.setRequestHeader('Content-Type', 'multipart/form-data');
xhr.send(formData);
However, when the method is executed on the server, the post body contains no files. The following is from ASP.NET MVC4:
[HttpPost]
public JsonResult AnalyseFile()
{
int filesCount = Request.Files.Count;
if(filesCount == 0) { throw new Exception('no files...'); }
// do stuff
}
The Files collection contains no files and I can't figure out why. Any help appreciated.
Upvotes: 0
Views: 388
Reputation: 1027
In the View, you can do:
<form>
<input name="input1" id="input1"/>
<input name="input2" id="input2"/>
<input name="input3" id="input3"/>
...
<input id="SelectedFile" name="SelectedFile" type="file"/>
</form>
And Javascript:
function AttLogic(_url, _data, _callback) {
$.ajax({
url: _url,
type: 'POST',
xhr: function () {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) { }
return myXhr;
},
data: _data,
cache: !1,
success: _callback,
contentType: !1,
processData: !1
});
}
function FormDataCustom(f) {
var __frm = jQuery(f), data = new FormData(f);
$(':disabled[name]', __frm).each(function () {
data.append(this.name, $(this).val());
});
return data;
}
function SaveLogic(){
var dt = FormDataCustom(document.forms[0]);
AttLogic(yourUrl, dt, function (r) {
//do something here
});
}
In the Controller:
public ActionResult Save(parameter1,parameter1,..., List<HttpPostedFileBase> SelectedFile)
{
//do something here
}
Upvotes: 1
Reputation: 6132
You will need to read the MultiPartFormData from the Request.
As per this post:
Your method will look something like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
namespace Some.Namespace
{
public class SomeController : ApiController
{
[HttpPost]
public async Task<JsonResult> AnalyseFile()
{
if (!Request.Content.IsMimeMultipartContent())
{
//If not throw an error
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider("c:\\tmp\\uploads");
// Read the MIME multipart content using the stream provider we just created.
IEnumerable<HttpContent> bodyparts = await Request.Content.ReadAsMultipartAsync(streamProvider);
// Get a dictionary of local file names from stream provider.
// The filename parameters provided in Content-Disposition header fields are the keys.
// The local file names where the files are stored are the values.
//depending on your version of .net, this might have been changed to FileData instead.
// see: https://msdn.microsoft.com/en-us/library/system.net.http.multipartformdatastreamprovider(v=vs.118).aspx
IDictionary<string, string> bodyPartFileNames = streamProvider.BodyPartFileNames;
//rest of code here
}
}
I haven't tested the above code, but it should point you in the right direction.
Also have a look at How To Accept a File POST
For a more recent article: https://code.msdn.microsoft.com/AngularJS-with-Web-API-22f62a6e
Upvotes: 0