views:

103

answers:

1

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.

+1  A: 

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.

Darin Dimitrov
My actions have a view model in their signature and a HttpPostedFileBase and my view model class contains a byte[] public property. I then copy the contents of HttpPostedFileBase to my byte[] aray. Why? Because I cannot have HttpPostedFileBase as a type for my property because I am doing serialization for persistance. Even if used some DB for storing data I would still need to put it into byte array to be able to save it in DB as Image type. So I was wondering if the default binder can automatically bind to byte[] array.
mare
To make it easier for you to understand what I am doing, let's just say that I almost never save uploaded files to disk like you provided an example for. If there's a file uploaded it gets saved to XML or DB.
mare
You should be using ViewModels which are close to the Views and contain properties such as `HttpPostedFileBase`. Those ViewModels should not be persisted. You should have a mapping between those ViewModels and the business model that might contain `byte[]` if you will. Also the save to file was just an example. You could call your repository by passing it the `byte[]` which will take care of storing it in a database (As a side note I don't think it is a good idea to store uploaded files into a SQL database).
Darin Dimitrov
Yeah that's how I was doing so far - using HttpPostedFileBase and manually copying it over to byte[], I just thought if there's another way. I actually like storing files in the DB - that way all the content is in one place, DB gets backed up and is fully restorable along with files, files are not exposed to sysadmin's (and potential others) on the filesystem so they can't get accidentally deleted or modified in any way and you can forget about them. We had huge problems when migrating sites that had files on filesystem and they forgot to migrate them.
mare