asp.net-mvc 上传包含在 MVC 模型中的图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20446580/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Upload image included in MVC model
提问by Rob Bowman
I have the following model:
我有以下模型:
public class Photo
{
public int PhotoId { get; set; }
public byte[] ImageData { get; set; }
public DateTime DateUploaded { get; set; }
public string Description { get; set; }
public bool IsActive { get; set; }
}
I would like the user to be able to enter the details for the photo then post the model the the controller. My controller action is as follows:
我希望用户能够输入照片的详细信息,然后将模型发布到控制器。我的控制器操作如下:
[HttpPost]
public ActionResult Create(WilhanWebsite.DomainClasses.Photo photo)
{
if (ModelState.IsValid)
{
photo.DateUploaded = DateTime.Now;
_context.Photos.Add(photo);
_context.SaveChanges();
return RedirectToAction("Index");
}
//we only get here if there was a problem
return View(photo);
}
My view is as follows:
我的看法如下:
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Photo</h4>
<hr />
@Html.ValidationSummary(true)
<div class="form-group">
@Html.LabelFor(model => model.ImageData, new { @class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="uploadImages" class="input-files" />
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.DateUploaded, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.DateUploaded)
@Html.ValidationMessageFor(model => model.DateUploaded)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Description, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Description)
@Html.ValidationMessageFor(model => model.Description)
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.IsActive, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.IsActive)
@Html.ValidationMessageFor(model => model.IsActive)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
The view is displayed ok and allows the user to select a file from their local disk and enter the other model details. My problem is that although the model is posted to the controller ok, the Description, Date and IsActive flags are populated ok - the Image data is null.
视图显示正常,并允许用户从本地磁盘中选择文件并输入其他模型详细信息。我的问题是,尽管模型已发布到控制器正常,但描述、日期和 IsActive 标志填充正常 - 图像数据为空。
Could anyone please let me know what I need to change so that the byte array for the photo is included in the model posted to the controller?
谁能让我知道我需要更改什么,以便照片的字节数组包含在发布到控制器的模型中?
回答by Darin Dimitrov
The file input in your view has a name uploadImages. I can't see a property with this name in your view model. You seem to have some ImageDataproperty which is a byte array, but there doesn't seem to be a corresponding input field with this name in your view.
您视图中的文件输入有一个名称uploadImages。我在您的视图模型中看不到具有此名称的属性。您似乎有一些ImageData属性是一个字节数组,但在您的视图中似乎没有具有此名称的相应输入字段。
This explains why you get null. You could make this work by respecting the convention. So for example if you intend to have such an input field in your view:
这解释了为什么你得到空值。您可以通过遵守约定来完成这项工作。例如,如果您打算在视图中包含这样的输入字段:
<input type="file" name="uploadImages" class="input-files" />
then make sure that you have a property on your view model with the same name. And of course of type HttpPostedFileBase.
然后确保您的视图模型上有一个同名的属性。当然还有 type HttpPostedFileBase。
public HttpPostedFileBase UploadImages { get; set; }
Also in your view make sure you are setting the proper content type of multipart/form-data:
同样在您看来,请确保您设置了正确的内容类型multipart/form-data:
@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
...
}
You probably might want to go through the following blog postto better familiarize yourself with the basics of how uploading of files work in ASP.NET MVC. I've also written a similar answer herethat you might consult.
您可能希望阅读following blog post以更好地熟悉 ASP.NET MVC 中文件上传工作的基础知识。我还写了一个similar answer here你可以咨询的。
So once you add the HttpPostedFileBaseproperty with the UploadImagesname in your view model you could adapt your controller action to read the byte array and store it your ImageDataproperty:
因此,一旦您在视图模型中添加HttpPostedFileBase具有UploadImages名称的属性,您就可以调整控制器操作以读取字节数组并将其存储为您的ImageData属性:
[HttpPost]
public ActionResult Create(WilhanWebsite.DomainClasses.Photo photo)
{
if (ModelState.IsValid)
{
photo.DateUploaded = DateTime.Now;
photo.ImageData = new byte[photo.UploadImages.ContentLength];
photo.UploadImages.Read(photo.ImageData, 0, photo.ImageData.Length);
_context.Photos.Add(photo);
_context.SaveChanges();
return RedirectToAction("Index");
}
//we only get here if there was a problem
return View(photo);
}
Now bear in mind that this is an absolutely awful solution. Never do that in a real world application. In a correctly designed application you will have a view model that your controller action will take as a parameter. You're never gonna directly use your autogenerated EF model as parameter to your controller action. You will have a view model with the HttpPostedFileBaseproperty which will be mapped to your domain model.
现在请记住,这是一个绝对糟糕的解决方案。永远不要在现实世界的应用程序中这样做。在正确设计的应用程序中,您将拥有一个视图模型,您的控制器操作将其作为参数。您永远不会直接使用自动生成的 EF 模型作为控制器操作的参数。您将拥有一个带有HttpPostedFileBase属性的视图模型,该属性将映射到您的域模型。
So in a properly designed application you will have a PhotoViewModelview model class that your controller action will take.
因此,在正确设计的应用程序中,您将拥有一个PhotoViewModel控制器操作将采用的视图模型类。
回答by acfrancis
Change this line:
改变这一行:
@using (Html.BeginForm())
To this:
对此:
@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
Then change:
然后改变:
<input type="file" name="uploadImages" class="input-files" />
To:
到:
<input type="file" name="ImageData" class="input-files" />
Then change this line:
然后改变这一行:
public byte[] ImageData { get; set; }
To this:
对此:
public HttpPostedFileBase ImageData { get; set; }
Finally, use some code like this to read the image into a byte array:
最后,使用一些这样的代码将图像读入字节数组:
var bs = new byte[ImageData.ContentLength];
using (var fs = ImageData.InputStream)
{
var offset = 0;
do
{
offset += fs.Read(bs, offset, bs.Length - offset);
} while (offset < bs.Length);
}
回答by joe
View:
看法:
@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
...
<input type="file" id="ImageFile" name="ImageFile" .../>
...
}
Controller:
控制器:
[HttpPost]
public ActionResult Create(Photo photo, HttpPostedFileBase ImageFile)
{
byte[] buf = new byte[ImageFile.ContentLength];
ImageFile.InputStream.Read(buf, 0, buf.Length);
photo.ImageData = buf;
...
}

