有什么办法可以获取发布的文件(<input type="file" />) 参与 ASP.NET MVC 中的模型绑定 无需手动查看自定义模型绑定程序中的请求上下文,也无需创建仅将发布的文件作为输入的单独操作方法?

我本以为这会起作用:

class MyModel {
  public HttpPostedFileBase MyFile { get; set; }
  public int? OtherProperty { get; set; }
}

<form enctype="multipart/form-data">
  <input type="file" name="MyFile" />
  <input type="text" name="OtherProperty" />
</form>

public ActionResult Create(MyModel myModel) { ... } 

但考虑到上述场景, MyFile 甚至不是绑定上下文中值提供者值的一部分。 (OtherProperty 是,当然。)但如果我这样做的话它会起作用:

public ActionResult Create(HttpPostedFileBase postedFile, ...) { ... } 

那么,为什么当参数是模型时不会发生绑定,以及如何使其工作?我使用自定义模型活页夹没有问题,但是如何在自定义模型活页夹中执行此操作而不查看 Request.Files["MyFile"]?

为了一致性、清晰度和可测试性,我希望我的代码能够自动绑定模型上的所有属性,包括那些绑定到已发布文件的属性,而无需手动检查请求上下文。我目前正在使用测试模型绑定 斯科特·汉塞尔曼(Scott Hanselman)所写的方法.

或者我以错误的方式处理这件事?你会如何解决这个问题?或者由于 Request.Form 和 Request.Files 之间的分离历史,这在设计上是不可能的吗?

有帮助吗?

解决方案

原来的原因在于,ValueProviderDictionary只查找Request.FormRouteDataRequest.QueryString填充模型中的绑定上下文值提供字典。因此,有没有办法让一个自定义的模型绑定,允许发布文件,参与模型,而无需在请求上下文中直接检查文件的集合结合。这是我发现来完成同样的事情最接近的方式:

public ActionResult Create(MyModel myModel, HttpPostedFileBase myModelFile) { }

只要myModelFile实际上是file输入表单字段的名称,没有必要对任何自定义的东西。

其他提示

另一种方法是添加一个隐藏字段具有相同的名称作为输入:

<input type="hidden" name="MyFile" id="MyFileSubmitPlaceHolder" />

在DefaultModelBinder然后将看到一个字段和创建正确的粘合剂。

你看过吗 这个帖子 他链接到的 您链接到的那个 (通过 另一个...)?

如果没有,看起来很简单。这是他使用的模型活页夹:

public class HttpPostedFileBaseModelBinder : IModelBinder {
    public ModelBinderResult BindModel(ModelBindingContext bindingContext) {
        HttpPostedFileBase theFile =
            bindingContext.HttpContext.Request.Files[bindingContext.ModelName];
        return new ModelBinderResult(theFile);
    }
}

他将其注册在 Global.asax.cs 如下:

ModelBinders.Binders[typeof(HttpPostedFileBase)] = 
    new HttpPostedFileBaseModelBinder();

并以如下形式发布帖子:

<form action="/File/UploadAFile" enctype="multipart/form-data" method="post">
    Choose file: <input type="file" name="theFile" />
    <input type="submit" />
</form>

所有代码都是直接从博客文章中复制的......

您并不需要注册一个定制绑定,HttpPostedFileBase默认情况下,在框架中注册的:

public ActionResult Create(HttpPostedFileBase myFile)
{
    ...
}

它有助于而不是向看书每一次在一段时间,仅仅在博客和网络论坛依赖

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top