bzl*_*zlm 24 asp.net-mvc defaultmodelbinder modelbinders httppostedfilebase
有没有办法让发布的文件(<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) { ... }
Run Code Online (Sandbox Code Playgroud)
但鉴于上述情况,MyFile
甚至不是绑定上下文中值提供者值的一部分.(OtherProperty
当然是.)但如果我这样做,它会起作用:
public ActionResult Create(HttpPostedFileBase postedFile, ...) { ... }
Run Code Online (Sandbox Code Playgroud)
那么,当参数是模型时,为什么没有绑定发生,我怎样才能使它工作?我使用自定义模型绑定器没有问题,但是如何在不看的情况下在自定义模型绑定器中执行此操作Request.Files["MyFile"]
?
为了保持一致性,清晰度和可测试性,我希望我的代码能够自动绑定模型上的所有属性,包括绑定到已发布文件的属性,而无需手动检查请求上下文.我目前正在使用Scott Hanselman撰写的方法测试模型绑定.
或者我是以错误的方式解决这个问题?你怎么解决这个问题?或者,由于Request.Form和Request.Files之间的分离历史,这是不可能的设计?
bzl*_*zlm 30
事实证明,原因是ValueProviderDictionary
只查看Request.Form
,RouteData
并Request.QueryString
在模型绑定上下文中填充值提供程序字典.因此,自定义模型绑定器无法允许已发布的文件参与模型绑定,而无需直接检查请求上下文中的文件集合.这是我发现完成同样事情的最接近的方式:
public ActionResult Create(MyModel myModel, HttpPostedFileBase myModelFile) { }
Run Code Online (Sandbox Code Playgroud)
只要myModelFile
实际上是file
输入表单字段的名称,就不需要任何自定义的东西.
Bri*_*nce 14
另一种方法是添加一个与输入同名的隐藏字段:
<input type="hidden" name="MyFile" id="MyFileSubmitPlaceHolder" />
Run Code Online (Sandbox Code Playgroud)
然后DefaultModelBinder将看到一个字段并创建正确的绑定器.
如果没有,它看起来很简单.这是他使用的模型绑定器:
public class HttpPostedFileBaseModelBinder : IModelBinder {
public ModelBinderResult BindModel(ModelBindingContext bindingContext) {
HttpPostedFileBase theFile =
bindingContext.HttpContext.Request.Files[bindingContext.ModelName];
return new ModelBinderResult(theFile);
}
}
Run Code Online (Sandbox Code Playgroud)
他注册Global.asax.cs
如下:
ModelBinders.Binders[typeof(HttpPostedFileBase)] =
new HttpPostedFileBaseModelBinder();
Run Code Online (Sandbox Code Playgroud)
以及表单如下所示的帖子:
<form action="/File/UploadAFile" enctype="multipart/form-data" method="post">
Choose file: <input type="file" name="theFile" />
<input type="submit" />
</form>
Run Code Online (Sandbox Code Playgroud)
所有代码都直接从博客文章中复制出来......
归档时间: |
|
查看次数: |
17366 次 |
最近记录: |