После успешной загрузки изображения в mvc 3, но при редактировании изображение исчезает - PullRequest
4 голосов
/ 10 декабря 2011

Я читаю Pro ASP.NET MVC 3 Framework от Apress.Я следую примеру загрузки и отображения изображений.Проблема в том, что он отлично работает при загрузке изображений в продукты, но если позже я захочу, например, отредактировать описание, а затем сохранить продукт, изображение исчезнет.Я понимаю, что проблема заключается в том, что при сохранении продукта я не передаю данные изображения, потому что загрузка изображения пуста, а context.SaveChanges () сохраняет каждое поле данных, включая пустые поля данных изображения.

Я застрял, и я был бы очень признателен, если бы кто-нибудь мог мне помочь!

Это часть страницы редактирования:

<label>Image</label> 
if (Model.ImageData == null)
{ 
    @:Null
}
else
{ 
    <img id="imageFile" runat="server" src="@Url.Action("GetImage", "Product", new { Model.Name })" /> 
}
<label>Upload image:</label>
<input type="file" name="Image" runat="server"  />

При обновлении:

public ActionResult Edit(Product product, HttpPostedFileBase image)
    {
        if (ModelState.IsValid)
        {
            if (image != null && image.ContentLength > 0)
            {
                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} har sparats", product.Name);
            return RedirectToAction("Index");
        }
        else
        {
            return View(product);
        }
    }

Сохранение товара:

public void SaveProduct(Product product)
    {
        if (product.ProductID == 0)
        {
            context.Products.Add(product);
        }
        else
        {
            context.Entry(product).State = EntityState.Modified;
        }
        int result = context.SaveChanges();
    }

Ответы [ 3 ]

4 голосов
/ 11 декабря 2011

Вы правильно понимаете проблему: когда вы помечаете Product как EntityState.Modified EF помечает все его свойства измененными.Поэтому, когда ваш текущий Product исходит от контроллера и у него нет изображения, EF удаляет его из БД при вызове SaveChanges().
. Я вижу два варианта:

  1. Вы загружаете исходный Product и просто обновляете необходимые свойства instread, используя EntityState.Modified:

    var productInDb = context.Products.Find(product.Id);
    productInDb.Name = product.Name;
    productInDb.Description = product.Description;
    if (product.ImageData !=null )
    {
        productInDb.ImageData = product.ImageData;
        productInDb.ImageMimeType = product.ImageMimeType;
    }
    

    В этом случае вам необходимо вручную установить каждое свойство в Product.

  2. После того, как вы пометили ваш Product как измененный, вы заново устанавливаете значения изображения из БД:

    context.Entry(product).State = EntityState.Modified;
    if (product.ImageData == null)
    {
        var databaseValues = context.Entry(product).GetDatabaseValues();
        product.ImageData = (byte[])databaseValues["ImageData"];
        product.ImageMimeType = (string)databaseValues["ImageMimeType"];
    }
    

    В этом случае вам нужно только повторно-установите свойства, связанные с изображением.

В обеих реализациях невозможно удалить ImageData во время обновления.

0 голосов
/ 22 июля 2015

У меня была похожая проблема. Когда я добавил @Html.HiddenFor(model => model.Image) в окно редактирования, он отлично прошел imageURL.

0 голосов
/ 15 февраля 2012

Если вы попробуете второй вариант, предоставляемый @nemesv, и ваши классы сущностей находятся в другом пространстве имен относительно вашего DbContext, то вы получите исключение, вызванное структурой сущностей, как описано здесь:

entry.GetDatabaseValues ​​() throw EntitySqlException

Тип "XXX" может не найден Убедитесь, что необходимые схемы загружены и пространства имен импортированы правильно.

http://social.msdn.microsoft.com/Forums/en/adodotnetentityframework/thread/fa67aa0e-3bca-44a5-9e00-af6362a539a7

Кажется, что есть обходной путь, но это не приятно. Это позволяет изображению оставаться связанным с продуктом.

Вот как я это сделал:

if (product.ImageData == null)
{
    // Get Product Context reference
    var productContext = context.Entry(product);
    productContext.State = EntityState.Modified;

    // Copy client values and reload orignal product values from DB.
    var clientValues = productContext.CurrentValues.Clone().ToObject();
    productContext.Reload();
    productContext.CurrentValues.SetValues(clientValues);

    // Get database values (Original)
    var currentValues = productContext.Entity;
    var databaseValues = (Product)productContext.OriginalValues.ToObject();

    // Change image properties to match original values
    productContext.Entity.ImageData = databaseValues.ImageData;
    productContext.Entity.ImageMimeType = databaseValues.ImageMimeType;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...