views:

472

answers:

3

I have a field of type image in my database which is mapped as binary in my model (ADO.NET Entity Framework).

But somehow the image that I get from the input file box is not being passed to the object. I know this because I debuged my action and the object Language (the image I trying to upload to the database is a flag) has the property Flag set to null and that is very bad! It should contain the image uploaded. Do I have to do something else?

Below is my form html code and my action code:

<% using (Html.BeginForm("Create", "Language", FormMethod.Post, 
          new {enctype="multipart/form-data"})) {%>
    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="Id">Id:</label>
            <%= Html.TextBox("Id") %>
            <%= Html.ValidationMessage("Id", "*") %>
        </p>
        <p>
            <label for="Name">Name:</label>
            <%= Html.TextBox("Name") %>
            <%= Html.ValidationMessage("Name", "*") %>
        </p>
        <p>
            <label for="Flag">Flag:</label>
            <!--
            File box is a helper that I got from this link:
            http://pupeno.com/blog/file-input-type-for-forms-in-for-asp-net-mvc/
            -->
            <%= Html.FileBox("Flag")  %>
            <%= Html.ValidationMessage("Flag", "*") %>
        </p>
        <p>
            <label for="IsDefault">IsDefault:</label>
            <%= Html.TextBox("IsDefault") %>
            <%= Html.ValidationMessage("IsDefault", "*") %>
        </p>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

<% } %>

I am using Visual Studio 2008.

[AcceptVerbs(HttpVerbs.Post)]  
public ActionResult Create(Language language)  
{  
    // Here language.Flag is null. Shouldn't the Flag property be a
    // binary field ready to be stored in the database along with the others?
    if (!ModelState.IsValid || !_service.CreateLanguage(language))  
    {  
        return View("Create", language);  
    }  
    return RedirectToAction("Index");  
}

What am I doing wrong?

+2  A: 

I've been able to upload files by adding a HttpPostedFileBase parameter to my action method. I don't believe ASP.NET MVC will automatically populate a property on the language parameter for you under these circumstances.

David Andres
So, how can I populate that property? Thank you!
Fabio Milheiro
It was populated automatically for me. All I had to do was include the HttpPostedFileBase parameter. In markup, I didn't use Html helpers (though this should be ok). I simply wrote out <input type="file" ... />
David Andres
+1  A: 

File uploads work totally differently to normal post fields. You have the uploads in Request.Files. I'm doing something like this to pick it up:

if (Request.Files.Count != 1 || Request.Files[0].ContentLength == 0) {
    ModelState.AddModelError("Picture", "Picture is missing");
} else if (!IsImage(Request.Files[0].ContentType)) {
    ModelState.AddModelError("Picture", "The picture must be a JPEG or PNG");
} else {
    try {
        Save(Request.Files[0].InputStream);
    } catch {
        ModelState.AddModelError("Picture", "Something is wrong with the picture, we couldn't open it");
    }
}

IsImage and Save are actually much more complex in my code than that. If you want to save it to a model and database, you'll need to convert the stream into a byte array.

J. Pablo Fernández
A: 

Thank you for your responses, but fortunately I found a better way.

I changed the action method signature:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult Create(Language language)

to:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult Create(HttpPostedFileBase Flag, Language language)

Then I attribute the Flag filename to language.Flag and keep only the reference to where the file is (This is because we decided to keep the database as small as possible, but I am sure this new signature would work as well to convert the file to database).

Hope this helps other people too!

Sorry I can't give you a thumbs up. Not enough reputation...

Fabio Milheiro