Apress Pro Asp.net MVC Framework 3 - SportsStore Edit Product not working?
Asked Answered
E

7

12

G’day All, has anyone purchased the ALPHA of Apress Pro Asp.net MVC Framework 3 and created the SportsStore? I can’t for the life of me edit products and have the DB update successfully? No errors are displayed and unit tests all function, but no successful ‘edit’ i.e. I change some details, click save, it reports successful – I then check the results, and nothing has happened? Did anyone else find this when working through the SportsStore? Any advice will be greatly appreciated.

Cheers.

Euraeurasia answered 15/6, 2011 at 8:18 Comment(3)
For those that have the same problem, I had to add: context.Entry(product).State = EntityState.Modified; //using system.data; to the EFProductRepository / SaveProduct. Wouldn't work for me otherwise - and I followed the examples implicitly.Euraeurasia
Omg, i thought i did something wrong! Great Question here! ++1Miliary
I have not been able to get the source to work Can someone zip up a working version ? I have in compiling fine but its having problems with Ninject it seemsImperfect
L
12

The state of the EF object needs to be updated before saving.

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


            int result = context.SaveChanges();

        }
Lid answered 8/9, 2011 at 18:19 Comment(0)
L
3

I can't yet post comments but I would like to add to MVC Newbie's comment by showing what your final method should read:

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

Also don't forget to add the extra using statement (again as mentioned by MVC Newbie):

//using system.data;
Lemos answered 15/9, 2011 at 7:56 Comment(1)
Hope this helps others (that have been unfortunate enough to waste their money on this Apress book) from wasting as much time as I have on this problem. The main thing to remember while using this book is NOT to assume it's you that is wrong when your code doesn't work. More often than not it will be the book's code. If it doesn't work search here for the code. ;) Although I feel I have learned more from the mistakes the book has (and it has a lot!) than the rest of the book! LOLLemos
E
1

Try the followings. The idea is that product param that MVC model binding to the Action method is not syn'ing with EF, so we need to assocaite it to the repository:

public ActionResult Edit(Product product)   
{
    if (ModelState.IsValid)
    {
        ((ObjectSet<Product>)repository.Products).ApplyCurrentValues(product);

        repository.SaveProduct(product);
        TempData["message"] = string.Format("{0} has been saved", product.Name);
        return RedirectToAction("Index");
    }
    else 
    {
        return View(product);
    }
}
Etna answered 25/7, 2011 at 10:45 Comment(0)
S
0

I came across the same issue using the final version of Apress Pro ASP.NET MVC3. Using the Visual Studio debugger I noticed that when the context.SaveChanges()(SportsStore.Domain.Concrete.EFProductRepoistory) was executed the context was not changed to the changes we made inside the Edit view. Though the product defined in the constructor of SaveProduct()

So i guessed all we had to do is change the Context.Products.Product to the product inside the constructor like this:

        else
        {
            context.Products.Find(product.ProductId) = product;
        }

unfortunately Visual Studio gave me this error:

Error 1 The left-hand side of an assignment must be a variable, property or indexer

So to make it work I had to do this:

        else
        {
            context.Products.Find(product.ProductID).Name = product.Name;
            context.Products.Find(product.ProductID).Description = product.Description;
            context.Products.Find(product.ProductID).Category = product.Category;
            context.Products.Find(product.ProductID).Price = product.Price;
        }

This does work. However I think this is far from ideal and not the best way to do this.

Is there a way to do this in a way where I just edit/update the whole Product object inside the context rather than edit every property one by one?

Salters answered 15/8, 2011 at 16:38 Comment(0)
H
0
public void SaveProduct(Product product)
{
    var prod = context.Products.SingleOrDefault(p => p.ProductID == product.ProductID);
    if (product.ProductID > 0)  
    {
        context.Products.Remove(prod);
    }
    context.Products.Add(product);            
    context.SaveChanges();
}
Herren answered 19/11, 2011 at 18:33 Comment(0)
R
-1

try this

 public ActionResult Edit(Product product)
    {
        if (ModelState.IsValid)
        {
            Product p = repository.Products.FirstOrDefault(x => x.ProductID == product.ProductID);
            if (p != null)
            {
                p.ProductID = product.ProductID;
                p.Price = product.Price;
                p.Category = product.Category;
                p.Description = product.Description;
                p.Name = product.Name;
            }
            else
                p = product;
            repository.SaveProduct(p);
            TempData["message"] = string.Format("{0} has been saved", product.Name);
            return RedirectToAction("Index");
        }
        else 
        {
            return View(product);
        }
    }

im beginner with mvc 3, but i think the model reference (product parameter) is a Product object that is not bind to EF Context

Repairman answered 20/7, 2011 at 3:15 Comment(0)
H
-1

Here is the answer

public void SaveProduct(Product product)
    {
        var prod = context.Products.SingleOrDefault(p => p.ProductID == product.ProductID);

        if (product.ProductID > 0)
        {
            context.Products.Remove(prod);
        }
            context.Products.Add(product);            
            context.SaveChanges();
    }
Herren answered 19/11, 2011 at 18:43 Comment(1)
This will create a new product with a different id of the original. This was also my first try to resolve this problem. And this also makes one request more to the database than stictly needed.Miliary

© 2022 - 2024 — McMap. All rights reserved.