我一直关注Apress Pro ASP.NET MVC 3框架书中的SportsStore示例项目,并尝试将这些概念应用到我的应用程序中。困扰我的一个方面是,在示例中,我可以将图像添加到产品中并将其保存到数据库中,但如果我编辑任何给定的产品,而不上传新的图像,则图像数据将被清除。我希望能够编辑产品,但如果从HTTP帖子返回的图像数据为空,我希望实体框架保留现有的图像数据(和内容类型)。如果没有上传新图像,如何命令EF不使用null更新此图像字段?
以下是来自SportsStore示例的编辑代码:
[HttpPost]
public ActionResult Edit(Product product, HttpPostedFileBase image)
{
if (ModelState.IsValid)
{
if(image != null)
{
product.ImageMimeType = image.ContentType;
product.ImageData = new byte[image.ContentLength];
image.InputStream.Read(product.ImageData, 0, image.ContentLength);
}
_repository.SaveProduct(product);
TempData["message"] = string.Format("{0} has been saved", product.Name);
return RedirectToAction("Index");
}
else
{
return View(product);
}
}
编辑:对于Rondel - 以下是产品类的定义
namespace SportsStore.Domain.Entities
{
public class Product
{
[HiddenInput(DisplayValue=false)]
public int ProductId { get; set; }
[Required(ErrorMessage = "Please enter a product name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please enter a description")]
[DataType(DataType.MultilineText)]
public string Description { get; set; }
[Required]
[Range(0.01, double.MaxValue, ErrorMessage = "Please enter a positive price")]
public decimal Price { get; set; }
[Required(ErrorMessage = "Please specify a category")]
public string Category { get; set; }
public byte[] ImageData { get; set; }
[HiddenInput(DisplayValue = false)]
public string ImageMimeType { get; set; }
}
}
编辑如何让EF只保存某些字段并让其他字段保持不变?
答案 0 :(得分:2)
这里的基本问题是,当您将Product
保存回数据库时,您将使用MVC3填充ImageMimeType
的任何值覆盖ImageData
和Product
字段来自FormCollection
。现在,您要检查是否image==null
但是您没有实现逻辑以重用旧的Product
图像信息。这是你想要做的:
if (ModelState.IsValid)
{
if(image != null)
{
product.ImageMimeType = image.ContentType;
product.ImageData = new byte[image.ContentLength];
image.InputStream.Read(product.ImageData, 0, image.ContentLength);
}
else
{
//set this Product image details from the existing product in the db
product.ImageMimeType= getImageMimeTypeForProduct(product.ProductId );
product.ImageData = getImageDataForProduct(product.ProductId );
}
_repository.SaveProduct(product);
TempData["message"] = string.Format("{0} has been saved", product.Name);
return RedirectToAction("Index");
}
else
{
return View(product);
}
显然,这两种方法并不存在,但这个想法是一样的。您希望从该产品的db获取现有值,并确保在保存它并覆盖值之前将这些值反映在Product
的本地版本中。
答案 1 :(得分:2)
我知道回复有点迟,但我现在正在完成这一章并遇到同样的问题。
我通过在编辑视图中添加隐藏字段来修复它,以保存ImageData数据。由于视图使用@ Html.EditorForModel,因此不会为字节数据类型呈现任何编辑器,因此视图无法看到此数据。
@model SportsStore.Domain.Entities.Product
@{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
<h1>Edit @Model.Name</h1>
@using (Html.BeginForm("Edit", "Admin", FormMethod.Post, new { enctype = "multipart/form-data"}))
{
@Html.EditorForModel()
// New hidden field here
@Html.Hidden("ImageData", Model.ImageData)
<div class="editor-label">Image</div>
<div class="editor-field">
@if (Model.ImageData == null)
{
@:None
}
else
{
<img width="150" height="150" src="@Url.Action("GetImage", "Product", new { Model.ProductID})" />
}
<div>Upload new image: <input type="file" name="Image" /></div>
</div>
<input type="submit" value="Save" />
@Html.ActionLink("Cancel and return to List", "Index")
}