ASP.NET MVC似乎正确地自动绑定HTML表单的文件输入字段和HttpPostedFileBase。另一方面,它无法从文件输入字段绑定到字节数组。我尝试了它并发出异常 - 无法转换为Base64的事情。我以前只在我的Model类上有字节数组属性,因为稍后我需要它来执行对象到XML文件的序列化。
现在我已经提出了这个解决方法,它运行正常,但我不确定这是否可行:
[DataContract]
public class Section : BaseContentObject
{
...
[DataMember]
public byte[] ImageBytes;
private HttpPostedFileBase _imageFile;
public HttpPostedFileBase ImageFile
{
get { return _imageFile; }
set
{
_imageFile = value;
if (value.ContentLength > 0)
{
byte[] buffer = new byte[value.ContentLength];
value.InputStream.Read(buffer, 0, value.ContentLength);
ImageBytes = buffer;
ImageType = value.ContentType;
}
}
}
[DataMember]
public string ImageType { get; set; }
}
答案 0 :(得分:4)
我认为你让你的模型与你的Controller紧密相连。通常的做法是:
public ActionResult AcceptFile(HttpPostedFileBase submittedFile) {
var bytes = submittedFile.FileContents;
var model = new DatabaseThing { data = bytes };
model.SaveToDatabase();
}
在这种情况下,您的模型不需要知道HttpPostedFileBase
,这是一个严格的ASP.NET概念。
如果你需要超出DefaultModelBinder
提供的复杂绑定(很多),通常的方法是在Global.asax
中注册专门的ModelBinder,然后接受你自己的Model类作为Action Method参数,比如这样:
在Global.asax
:
ModelBinders.Binders.Add(typeof(MyThing), new ThingModelBinder());
然后,此ModelBinder可以找到与表单一起发布的任何文件,并将该文件的内容绑定到Data
的{{1}}属性。
在你的控制器中:
Thing
在此操作方法中,您的public ActionResult AcceptThing(MyThing thing) {
thing.Data.SaveToDatabase();
}
将处理所有绑定,使其对Controller和模型都透明。
在这种情况下,修改您的实际Model类以了解并使用ASP.NET。毕竟,你的模型类应该代表你的实际数据。
答案 1 :(得分:0)
显然,MVC Futures 2有很大的变化(刚刚发现),特别是关于Model Binders。
例如,我的输入文件绑定到字节数组的问题,现在有一个绑定器:
•BinaryDataModelBinderProvider - 将绑定base-64编码输入处理为byte []和System.Linq.Data.Binary模型。