Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to upload a file with ASP.NET MVC

I am trying to upload a file with ASP.NET MVC.

The following code work perfectly fine:

// Read in the image data.
byte[] binaryData = null;
HttpPostedFileBase uploadedFile = Request.Files["ImageFileName"];
if (uploadedFile != null &&
    uploadedFile.ContentLength > 0)
    {
        binaryData = new byte[uploadedFile.ContentLength];
        uploadedFile.InputStream.Read(binaryData, 
                                      0,
                                      uploadedFile.ContentLength);
    }

But what I am trying to do is use the new FileCollectionModelBinder found in the futures assembly.

I've found these two blog posts here and here explaining what to do. I follow these instructions but havne't had any luck -> the file object is always null.

Here is my method.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Include = "Subject, Content")]
                           Post post, 
                           HttpPostedFileBase file)
{
    UpdateModel(post);
    ...
}

Notice how i'm trying to upload a file AND upload some post information, to a Post object.

Can anyone make any suggestions?

For the record, I have wired up the ModelBinder in my global.asax.cs. I've also made sure the form is a post with the enctype added:-

<form method="post" enctype="multipart/form-data" action="/post/create">
like image 743
Pure.Krome Avatar asked Apr 05 '09 05:04

Pure.Krome


3 Answers

No bloody way :(

I figured out that answer and it's pretty lame.

I had to have the argument NAME being identical to the Id/Name values of the input type="file" element!!! (not sure if it's either or both element values ... i didn't check that bit out).

so this is the answer.

Html input element. (note the value of the Id/Name)

<input type="file" id="imageFileName" name="imageFileName" class="upload" />

Controller method

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Include = "Subject, Content")]Post post,
    HttpPostedFileBase imageFileName)
{
...
}

shees!

like image 168
Pure.Krome Avatar answered Oct 18 '22 03:10

Pure.Krome


Remember you also need to open your form like this:

<form enctype="multipart/form-data" ...
like image 20
joshcomley Avatar answered Oct 18 '22 05:10

joshcomley


Not sure if this is relevant to the question, but I've just found a way to get model binding for HttpPostedFileBase working, within complex objects. Unfortunately I had to make a change to the ASP.NET MVC source code, so it isn't for everybody.

In System.Web.Mvc.ValueProviderDictionary.PopulateDictionary(), the value provider is being populated with the contents of Request.Form, Request.QueryString, and RouteData - but NOT Request.Files. Add the following lines to "fix" this (I say "fix" because there may be a reason the ASP.NET MVC team didn't do it in the first place).

HttpFileCollectionBase files = ControllerContext.HttpContext.Request.Files;
if (files != null)
{
    string[] keys = files.AllKeys;
    foreach (string key in keys)
    {
        HttpPostedFileBase file = files[key];
        ValueProviderResult result = new ValueProviderResult(file, file.FileName, currentCulture);
        AddToDictionaryIfNotPresent(key, result);
    }
}
like image 1
Tim Jones Avatar answered Oct 18 '22 03:10

Tim Jones