0

I have Entity Framework model which contains reference to other Entity like

public class Product
{
    [Key]
    public int ProductID { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public virtual Shop Shop { get; set; }

    [Required]
    public double Price { get; set; }
}

I would like to create Edit View which contain Shop selector (DropDown).

By default I have created basic MVC Controller with Entity model connected, which created Edit like:

public ActionResult Edit(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    Product product = db.Products.Find(id);

    if (product == null)
    {
        return HttpNotFound();
    }
    return View(product);
}

and View does not contain Shop selector.

I have tried to add DropDown like:

@Html.DropDownListFor(product => product.Shop, (SelectList)ViewBag.Shops)

But in POST method, Shop entity is null.

How to handle that?

2 Answers 2

1

Create a view model to represent what you want to display

public class ProductVM
{
  public int ProductID { get; set; }
  [Required]
  public string Name { get; set; }
  [Required]
  public int? ShopID { get; set; }
  [Required]
  public double Price { get; set; }
  public SelectList ShopList { get; set; }
}

and in your controller, map your model to the view model

public ActionResult Edit(int? ID)
{
  ....
  Product product = db.Products.Find(id);
  ProductVM model = new ProductVM();
  // map properties
  ....
  // populate select list (assumes Shop has properties ID and Name)
  model.ShopList = new SelectList(db.Shops, "ID", "Name");
  return View(product);
}

and in your view

@model ProductVM
....
@Html.DropDownListFor(m => m.ShopID, Model.ShopList, "--Select shop--")
@Html.ValidationMessageFor(m -> m.ShopID)

this will post back the model with the selected ID of the Shop. Select controls post back single values so you cannot post back a complex object such as Shop. The POST method would be

[HttpPost]
public ActionResult Edit(ProductVM model)
{
  ....
}

Note you can use tools such as automapper to make mapping easier

Sign up to request clarification or add additional context in comments.

2 Comments

can you please add how POST method will look like in this case?
I mean, If I have in my Entity model property Shop, and in my viewModel property ShopID, I need to write method to convert back VM to model like: Shop = db.Shops.Find(this.ShopID)? right?
1

I hope this helps.

Model for Product:

public class Product
{
    public int ProductID { get; set; }
    public string Name { get; set; }
    public int ShopID { get; set; }
    public double Price { get; set; }
}

Then a ViewModel for Product:

public class ProductViewModel
{
    public Product Model { get; set; }
    public IEnumerable<SelectListItem> Shops{ get; set; }

    public ProductViewModel()
    {
         GetShops();
    }

    public void GetShops()
    {
        Shops = new List<SelectListItem>();

        var collectionShops = GetShopsFromDatabase();
        Shops.AddRange(
                collectionShops.Select(
                    contract =>
                    new SelectListItem
                    {
                        Text = contract.ShopDescription,
                        Value = contract.ShopID.ToString()
                    }));
    }
}

In your View:

@model ProductViewModel

....


@Html.DropDownListFor(x => x.Model.ShopID, Model.Shops, new { @title = "Please select a shop" })

1 Comment

First, Product is a data model related to EF and should not be changed. That's why we use view models. Second, view models should contain that properties relating to the view, not methods and certainly not database code. That's the responsibility of the controller.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.