Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mvc upload file with model - second parameter posted file is null

I have a simple model with 1 string property which I render on a simple view.

the view looks like the following:

@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { encType="multipart/form-data" }))
{
    @Html.TextBoxFor(m => m.FirstName)
    <br /><br />

    <input type="file" name="fileUpload" /><br /><br />
    <input type="submit" value="submit me" name="submitme" id="submitme" />
}

Controller is this:

[HttpPost]
public ActionResult UploadFile(UploadFileModel model, HttpPostedFileBase file)
{
   // DO Stuff
   return View(model);
}

Now, when I submit, the model DOES get populated but the second parameter being HttpPostedFileBase is null. However when doing Request.Files - it does seem to show there is a file in the Request being posted. How can I actually get the second parameter to bind?

like image 421
Ahmed ilyas Avatar asked Feb 10 '14 12:02

Ahmed ilyas


2 Answers

Why not add the uploaded files to your model like this:

public class UploadFileModel 
{
    public UploadFileModel()
    {
        Files = new List<HttpPostedFileBase>();
    }

    public List<HttpPostedFileBase> Files { get; set; }
    public string FirstName { get; set; }
    // Rest of model details
}

Then change your view to this:

@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { encType="multipart/form-data" }))
{
    @Html.TextBoxFor(m => m.FirstName)
    <br /><br />

    @Html.TextBoxFor(m => m.Files, new { type = "file", name = "Files" })<br /><br />
    <input type="submit" value="submit me" name="submitme" id="submitme" />
}

Then your files will be posted back as follows:

public ActionResult UploadFile(UploadFileModel model)
{
    var file = model.Files[0];
    return View(model);
}
like image 114
hutchonoid Avatar answered Sep 21 '22 16:09

hutchonoid


For dealing with a single file input you can define a HttpPostedFileBase property within the ViewModel:

public class SomeModel() 
{ 
    public SomeModel() 
    {
    }

    public HttpPostedFileBase SomeFile { get; set; }
}

And then implement it in the following way:

View:

@model SomeModel

@using (Html.BeginForm(
    "Submit", 
    "Home", 
    FormMethod.Post, 
    new { enctype="multipart/form-data" }))
{
    @Html.TextBoxFor(m => m.SomeFile, new { type = "file" })
    <input type="submit" value="Upload" 
        name="UploadButton" id="UploadButton" />
}

Controller:

[HttpPost]
public ActionResult Submit(SomeModel model)
{
    // do something with model.SomeFile

    return View();
}

In case you need to deal with multiple files, you can either:

  • create multiple properties and implement them separately just like the one above;
  • change the public HttpPostedFileBase SomeFile property to something like public List<HttpPostedFileBase> SomeFiles and then span multiple @Html.TextBoxFor(m => m.SomeFile, new { type = "file" }) controls to have them all within that list.

In case you need additional info check out this blog post that I wrote on the topic.

like image 32
Darkseal Avatar answered Sep 18 '22 16:09

Darkseal