@Html.DisplayListFor - ViewModel for Foreign Key Drop List

760 Views Asked by At

I have create a view model:

public class CreateChemicalViewModel
{
    public IEnumerable<Site> Sites { get; set; }
    public Chemical Chemical { get; set; }
}

I have a controller that makes a new instance of the view model and pushes it to the view:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(Chemical chemical)
    {
        CreateChemicalViewModel viewModel = new CreateChemicalViewModel();
        viewModel.Sites = siteRepository.Sites;
        viewModel.Chemical = chemical;

        if (ModelState.IsValid)
        {
            chemicalRepository.Create(chemical);
        }
        else
        {
            // Something wrong with the values
        }
        return View(viewModel);
    }

    public ViewResult Create()
    {
        return View();
    }

I am trying to add a dropdown list that satisfies the relationship between a Site and a Chemical... But I can't figure out the syntax:

@model WebApplication.WebUI.Models.CreateChemicalViewModel

@{
    ViewBag.Title = "Create";
    Layout = "~/Views/_Main.cshtml";
}

<h2>Create</h2>

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Chemical</h4>
        <hr />
        @Html.ValidationSummary(true)

        <div class="form-group">
            @Html.LabelFor(model => model.Chemical.SiteID, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(model => model.Chemical.SiteID, new SelectList( model => model.Sites, new SelectListItem() { Text = Model.Sites.Title, Value = Model.Sites.SiteID } )  
                //@* This line is not working, model.Sites.Title exists but the properties of the Site do not (Title and SiteID for example) *@
                @Html.ValidationMessageFor(model => model.Chemical.SiteID)
            </div>
        </div>
...        

}

<div>
    @Html.ActionLink("Back to List", "List")
</div>

Any ideas what I need to do if I wanted a dropdown list that lists the "Sites" using Key = Title and Value = SiteID so that the selected "Site" becomes the value for the Chemical relationship (SiteID)


Stack

[NullReferenceException: Object reference not set to an instance of an object.]
   ASP._Page_Views_Chemical_Create_cshtml.Execute() in c:\Users\James\Documents\Visual Studio 2013\Projects\Application\WebApplication.WebUI\Views\Chemical\Create.cshtml:24
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +272
   System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +121
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +131
   System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +695
   System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +382
   System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +431
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +39
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +116
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +529
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +106
   System.Web.Mvc.Async.<>c__DisplayClass28.<BeginInvokeAction>b__19() +321
   System.Web.Mvc.Async.<>c__DisplayClass1e.<BeginInvokeAction>b__1b(IAsyncResult asyncResult) +185
   System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +42
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +133
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +56
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +40
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +34
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +44
   System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +39
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +62
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +39
   System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +39
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(IAsyncResult asyncResult, ProcessRequestState innerState) +39
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70
   System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +40
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9688704
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
1

There are 1 best solutions below

6
On BEST ANSWER

Try this

@Html.DropDownListFor(model => model.Chemical.SiteID, new SelectList(Model.Sites, "SiteID", "Title", Model.Chemical!= null ? Model.Chemical.SiteID : null))  

EDIT: In your HttpGet "Create" action you need to return CreateChemicalViewModel because it contains dropdown items. Try this

public ViewResult Create()
{
    CreateChemicalViewModel viewModel = new CreateChemicalViewModel();
    viewModel.Sites = siteRepository.Sites;
    return View(viewModel);
}