Модель связывает 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 ответа

Решение

Я думаю, что вы позволяете вашей модели тесно соединяться с вашим контроллером. Обычный способ сделать это:

public ActionResult AcceptFile(HttpPostedFileBase submittedFile) {
  var bytes = submittedFile.FileContents;
  var model = new DatabaseThing { data = bytes };
  model.SaveToDatabase();
}

В этом случае вам не нужно знать о вашей модели HttpPostedFileBase, что является строго концепцией ASP.NET.

Если вам нужно сложное связывание помимо того, что DefaultModelBinder Поставки (что много), обычный способ заключается в регистрации специализированных ModelBinder в Global.asax и затем примите ваши собственные классы Model в качестве аргументов метода действия, например:

В Global.asax:

ModelBinders.Binders.Add(typeof(MyThing), new ThingModelBinder()); 

Этот ModelBinder может, например, найти любой файл, который был опубликован с формой, и связать содержимое этого файла с Data собственность вашего Thing,

И в вашем контроллере:

public ActionResult AcceptThing(MyThing thing) {
  thing.Data.SaveToDatabase();
}

В этом методе действий ваш ThingModelBinder обрабатывал бы все привязки, делая его прозрачным как для контроллера, так и для модели.

В этом случае нет необходимости изменять ваши фактические классы Model, чтобы они знали и работали с ASP.NET. В конце концов, классы вашей модели должны представлять ваши фактические данные.

По-видимому, в MVC Futures 2 произошли огромные изменения (только что это выяснилось), особенно в отношении Model Binder.

Например, проблема с моей привязкой входного файла к массиву байтов, теперь есть связыватель:

• BinaryDataModelBinderProvider - Обрабатывает связывание кодированного Base-64 ввода для моделей byte[] и System.Linq.Data.Binary.

Другие вопросы по тегам