Search code examples
asp.net-mvc-3editortemplates

How do I use editortemplates in MVC3 for complex types?


I have two classes, Vat and Product. Product has a property of IVat. I am trying to use editor templates in MVC to display a dropdown list of all the Vat objects when creating/editing a Product. For the dear life of me I cannot get this working.

I have the following code which displays the dropdown but it does not set the Vat for the Product when the form gets submitted.

Controller:

IList<IVatRate> vatRates = SqlDataRepository.VatRates.Data.GetAllResults();
ViewBag.VatRates = new SelectList(vatRates, "Id", "Description");

Add.cshtml

@Html.EditorFor(model => model.VatRate.Id, "VatSelector", (SelectList)ViewBag.VatRates)

VatSelector.cshtml

@model SelectList
@Html.DropDownList(
        String.Empty /* */,
            (SelectList)ViewBag.Suppliers, 
        Model
    )

I would be grateful if anyone can shed some light on this or even point me to a good example on the web somewhere...I have been stuck with this for quite a few days now.


Solution

  • I would use strongly typed views and view models as it makes things so much easier rather than ViewBag.

    So start with a view model:

    public class VatRateViewModel
    {
        public string SelectedVatRateId { get; set; }
        public IEnumerable<IVatRate> Rates { get; set; }
    }
    

    then a controller:

    public class HomeController: Controller
    {
        public ActionResult Index()
        {
            var model = new VatRateViewModel
            {
                Rates = SqlDataRepository.VatRates.Data.GetAllResults()
            };
            return View(model);
        }
    
        [HttpPost]
        public ActionResult Index(VatRateViewModel model)
        {
            // model.SelectedVatRateId will contain the selected vat rate id
            ...
        }
    }
    

    View:

    @model VatRateViewModel
    @using (Html.BeginForm())
    {
        @Html.DropDownListFor(
            x => x.SelectedVatRateId,
            new SelectList(Model.Rates, "Id", "Description")
        )
        <input type="submit" value="OK" />
    }
    

    And if you wanted to use editor template for the VatRateViewModel you could define one in ~/Views/Shared/EditorTemplates/VatRateViewModel.cshtml:

    @model VatRateViewModel
    @Html.DropDownListFor(
        x => x.SelectedVatRateId,
        new SelectList(Model.Rates, "Id", "Description")
    )
    

    and then whenever somewhere you have a property of type VatRateViewModel you could simply:

    @Html.EditorFor(x => x.SomePropertyOfTypeVatRateViewModel)
    

    which would render the corresponding editor template.