2

Apress Pro ASP.NET MVC 3 Framework 서적에서 SportsStore 예제 프로젝트를 수행하고 내 응용 프로그램에 개념. 저를 괴롭히는 한 가지 예는 샘플에서 이미지를 제품에 추가 할 수 있고 데이터베이스에 저장되지만, 주어진 제품을 편집하면 새 이미지를 업로드하지 않고 이미지 데이터가 지워집니다 . 제품을 편집 할 수 있기를 원하지만 HTTP 게시물에서 반환 된 이미지 데이터가 null 인 경우 엔 Entity Framework에서 기존 이미지 데이터 (및 컨텐트 유형)를 유지해야합니다. 새 이미지를 업로드하지 않은 경우 EF가이 이미지 필드를 null로 업데이트하지 않도록하려면 어떻게해야합니까? 여기MVC - 이미지가 HTTP Post (SportsStore 예제에서)에 다시 업로드되지 않은 경우 null 이미지 데이터를 저장하지 마십시오.

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

편집는 어떻게 만들 수있는 제품 클래스의 정의입니다 - 론델의 경우 :

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

편집 : 여기

는 SportsStore 샘플에서 편집 코드 EF는 특정 필드 만 저장하고 다른 필드는 데이터베이스에 그대로 둡니다.

+0

이미지 세부 정보를 담고있는 'Product' 클래스의 속성을 게시 할 수 있습니까? ImageMimeType 및 ImageData 필드를 사용하고 계십니까? – Rondel

+0

Rondel - 위의 제품 클래스를 추가했습니다. – bigmac

답변

2

여기에 기본적인 문제는 당신이 데이터베이스에 다시 Product을 저장할 때, 당신이 MVC3는 FormCollection에서와 그 Product를 채 웁니다 값 어떤으로 ImageMimeTypeImageData 필드를 덮어 쓰는 것입니다. 지금은 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의 로컬 버전에 반영되는지 확인하려고합니다.

+0

Rondel에게 감사드립니다. 그것에 대한 한가지 우려는 ... DB에서 다시 이미지를 저장하기 위해 데이터베이스에서 이미지를 가져와야하는 경우, 많은 불필요한 데이터가 앞뒤로 보내지는 결과를 가져 오지 않습니다 (특히 바이트 배열이 큰 경우)? 일부 필드가 채워지지 않은 경우 EF에 덮어 쓰지 말라고 단순히 알리는 방법이 없습니까? – bigmac

+0

무슨 뜻인지 알 겠어. 그러면이 문제를 해결할 수 있습니다. 그건 어렵지만, 당신의 dataContext에'Attach' 객체를 추가하고 속성을 저장하고자하는 곳에 .IsModified = true;를 설정하면됩니다. 그래도 리파지토리와 함께 작동하려면 약간의 수정이 필요할 수 있습니다. http://stackoverflow.com/questions/3642371/how-to-update-only-one-field-using-entity-framework 및 – Rondel

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") 
} 
+0

굉장한 빠른 수정 . – panzerblitzer

관련 문제