模型绑定HttpPostedFileBase,然后将文件存储到数据存储区

时间:2010-04-08 15:52:35

标签: asp.net-mvc xml-serialization httppostedfilebase

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; }
     }

2 个答案:

答案 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模型。