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