Reputation: 13083
Anyone managed to get default binder to work with input file control and property of type byte array?
If I have a property on my ViewModel named Image and a file input control on my view name Image, default binder issue this error:
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or a non-white space character among the padding characters.
Upvotes: 1
Views: 3552
Reputation: 11
You should create a custom model binder that associates directly your uploaded file to a byte[] field in your model.
Example:
public class CustomByteArrayModelBinder : ByteArrayModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var file = controllerContext.HttpContext.Request.Files[bindingContext.ModelName];
if (file != null)
{
if (file.ContentLength > 0)
{
var fileBytes = new byte[file.ContentLength];
file.InputStream.Read(fileBytes, 0, fileBytes.Length);
return fileBytes;
}
return null;
}
return base.BindModel(controllerContext, bindingContext);
}
}
You also have to remove the default model binder, and add yours (in Global.asax.cs, inside the Application_Start method):
ModelBinders.Binders.Remove(typeof(byte[]));
ModelBinders.Binders.Add(typeof(byte[]), new CustomByteArrayModelBinder());
This code were retired from this good article: http://prideparrot.com/blog/archive/2012/6/model_binding_posted_file_to_byte_array
Best regards :)
Upvotes: 1
Reputation: 1038710
Why do you need a byte[]
array? The default model binder works with HttpPostedFileBase:
<% using (Html.BeginForm("upload", "home", FormMethod.Post, new { enctype = "multipart/form-data" })) { %>
<input type="file" name="file" id="file" />
<input type="submit" value="Upload" />
<% } %>
And the controller action that will handle this:
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data"), fileName);
file.SaveAs(path);
}
return RedirectToAction("Index");
}
This works also with multiple files. You simply use IEnumerable<HttpPostedFileBase>
in the signature of the action method.
Upvotes: 3