将包含在MVC模型中的图像上传

21 浏览
0 Comments

将包含在MVC模型中的图像上传

我有以下的模型:

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

我想让用户能够输入照片的详细信息,然后将模型发布到控制器。我的控制器操作如下:

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

我的视图如下:

@using (Html.BeginForm()) 
{
@Html.AntiForgeryToken()

Photo

 


@Html.ValidationSummary(true) @Html.LabelFor(model => model.ImageData, new { @class = "control-label col-md-2" }) @Html.LabelFor(model => model.DateUploaded, new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.DateUploaded) @Html.ValidationMessageFor(model => model.DateUploaded) @Html.LabelFor(model => model.Description, new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.Description) @Html.ValidationMessageFor(model => model.Description) @Html.LabelFor(model => model.IsActive, new { @class = "control-label col-md-2" }) @Html.EditorFor(model => model.IsActive) @Html.ValidationMessageFor(model => model.IsActive) }

视图正常显示,并允许用户从其本地磁盘选择文件并输入其他模型详细信息。我的问题是,尽管模型已成功发布到控制器,但“Description”、“Date”和“IsActive”标志得到了良好的填充 — “Image”数据为空。

请问我需要更改什么,以便将照片的字节数组包含在发布到控制器的模型中?

admin 更改状态以发布 2023年5月24日
0
0 Comments

修改此行:

@using (Html.BeginForm()) 

为:

@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))

然后将下面的行:


修改为:


然后将此行:

 public byte[] ImageData { get; set; }

修改为:

 public HttpPostedFileBase ImageData { get; set; }

最后,使用类似以下代码将图像读入字节数组中:

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

0
0 Comments

你的视图中的文件输入具有名称uploadImages,但我无法在您的视图模型中找到具有此名称的属性。您似乎有一些ImageData属性,它是一个字节数组,但在您的视图中似乎没有相应的具有此名称的输入字段。

这就解释了为什么你得到了空值。你可以通过遵守惯例来使它正常工作。因此,例如,如果您打算在视图中使用这样的输入字段:


那么请确保您在视图模型中具有相同名称的属性。当然,它的类型是HttpPostedFileBase

public HttpPostedFileBase UploadImages { get; set; }

此外,请确保在视图中设置正确的内容类型multipart/form-data

@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    ...
}

您可能想要阅读一下以下博客文章,以更好地了解ASP.NET MVC中文件上传的基础知识。我还写了一个类似的答案供您参考。

因此,一旦您在视图模型中添加了UploadImages名称和HttpPostedFileBase属性,您可以调整控制器操作以读取字节数组并将其存储到您的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);
}

现在要记住,这是一个绝对糟糕的解决方案。在真实世界应用程序中永远不要这样做。在应用程序设计正确的情况下,您将具有视图模型,您的控制器操作将将其作为参数使用。您永远不会直接将自动生成的EF模型用作控制器操作的参数。您将具有具有HttpPostedFileBase属性的视图模型,该属性将映射到您的域模型中。

因此,在正确设计的应用程序中,您将具有一个名为PhotoViewModel的视图模型类,您的控制器操作将使用它。

0