views:

134

answers:

2

I can't have asp.net mvc 1.0 to bind HttpPostedFileBase for me.

this is my EditModel class.

public class PageFileEditModel
{
    public HttpPostedFileBase File { get; set; }
    public string Category { get; set; }
}

and this is my edit method header.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection formCollection, PageFileEditModel[] pageFiles)

and this is my HTML

<input type="file" name="pageFiles[0].File" />
<input type="text" name="pageFiles[0].Category" />
<input type="file" name="pageFiles[1].File" />
<input type="text" name="pageFiles[1].Category" />

Category is bind correctly, but File is always null.

I've verifed that the files indeed are in Request.Files.

The HttpPostedFileBaseModelBinder is added by default so can't figure out what is going wrong..

A: 

This is a specification.

Scott Hanselman's Computer Zen - ASP.NET MVC Beta released - Coolness Ensues

This is V1 RTW base model binder sample code.

1.Make custom model binder.

using System.Web.Mvc;

namespace Web
{
  public class HttpPostedFileBaseModelBinder : IModelBinder
  {
    public object BindModel(ControllerContext controllerContext, 
                            ModelBindingContext bindingContext)
    {
      var bind = new PostedFileModel();
      var bindKey = (string.IsNullOrEmpty(bindingContext.ModelName) ?
        "" : bindingContext.ModelName + ".") + "PostedFile";
      bind.PostedFile = controllerContext.HttpContext.Request.Files[bindKey];

      return bind;
    }
  }
}

2.Create model class.

using System.Web;

namespace Web
{
  public class PostedFileModel
  {
    public HttpPostedFileBase PostedFile { get; set; }
  }
}

3.Entry model binder in global.asax.cs.

protected void Application_Start()
{
  RegisterRoutes(RouteTable.Routes);
  ModelBinders.Binders[typeof(PostedFileModel)] = 
                 new HttpPostedFileBaseModelBinder();
}
takepara
already implemented in MVC 1.0 RTM
Carl Hörberg
I think unbinding HttpPostedFileBase on complex type.
takepara
+1  A: 

There's a bug in MVC 1 (fixed in MVC 2 RC) where HttpPostedFileBase objects aren't bound if they're properties on your model type rather than parameters to your action method. Workaround for MVC 1:

<input type="file" name="theFile[0]" />
<input type="hidden" name="theFile[0].exists" value="true" />
<input type="file" name="theFile[1]" />
<input type="hidden" name="theFile[1].exists" value="true" />

That is, for each file upload element foo have a foo.exists hidden input element. This will cause the DefaultModelBinder's short-circuiting logic not to kick in and it should correctly bind the HPFB property.

Levi
bam! to be exakt: <input type="file" name="pageFiles[0].File" /><input type="hidden" name="pageFiles[0].File.exists" value="true" />
Carl Hörberg