Created
October 22, 2011 09:50
-
-
Save Antaris/1305827 to your computer and use it in GitHub Desktop.
An updated model binder that supports async and non-async file uploads.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace AsyncUpload.Controllers | |
{ | |
public class HomeController : Controller | |
{ | |
public ActionResult Index() | |
{ | |
ViewBag.Message = "Welcome to ASP.NET MVC!"; | |
return View(); | |
} | |
public ActionResult About() | |
{ | |
return View(); | |
} | |
[HttpPost] | |
public ActionResult Upload(HttpPostedFileBase file) | |
{ | |
// Use the standard HttpPostedFileBase | |
return View(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace AsyncUpload.Models | |
{ | |
public class HttpPostedFileBaseModelBinder : IModelBinder | |
{ | |
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) | |
{ | |
var request = controllerContext.RequestContext.HttpContext.Request; | |
if (request.Files.Count > 0) | |
{ | |
var file = request.Files[bindingContext.ModelName]; | |
if (file != null && file.ContentLength > 0 && !string.IsNullOrEmpty(file.FileName)) | |
return file; | |
return null; | |
} | |
if (request.ContentLength > 0) | |
{ | |
string filename = request.Headers["X-File-Name"]; | |
if (string.IsNullOrEmpty(filename)) | |
return null; | |
string fileType = request.Headers["X-File-Type"]; | |
byte[] fileContent = new byte[request.ContentLength]; | |
request.InputStream.Read(fileContent, 0, request.ContentLength); | |
return new AsyncHttpPostedFile(filename, fileType, fileContent); | |
} | |
return null; | |
} | |
class AsyncHttpPostedFile : HttpPostedFileBase | |
{ | |
private readonly string _filename; | |
private readonly string _contentType; | |
private readonly int _contentLength; | |
private readonly byte[] _data; | |
public AsyncHttpPostedFile(string filename, string contentType, byte[] data) | |
{ | |
_filename = filename; | |
_contentType = contentType; | |
_contentLength = data.Length; | |
_data = data; | |
} | |
public override string FileName { get { return _filename; } } | |
public override string ContentType { get { return _contentType; } } | |
public override int ContentLength { get { return _contentLength; } } | |
public override Stream InputStream { get { return new MemoryStream(_data); } } | |
} | |
} | |
} |
Wait, it's not Async at all, it uses InputStream.Read, not InputStream.BeginRead or InputStream.ReadAsync
Where is async stuff here?
This gist is from 2011. By "async" - this was back in the day when you're performing "async" file uploads in a browser using AJAX. This is explicitly not modern C# async/await.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is based around Ben (@Buildstarted)'s blog post entitled "Asp.net MVC 3 file uploads using the FileApi" whereby we need to handle async file uploads which don't populate the
HttpRequest.Files
collection. We can build a new model binder to replace the existing implementation.