Didaxis
Didaxis

Reputation: 8746

DropDownListFor throwing ArgumentNullException

Not sure what's going on here...

My controller methods looks like this:

[HttpGet]
public ActionResult RequestAppointment()
{
    var appointmentRequest = new AppointmentRequest
    {
        Stylists = _repository.Stylists // <-- Debugging shows that Stylists IS being populated here
    };

    return View(appointmentRequest);
}

[HttpPost]
public ActionResult RequestAppointment(AppointmentRequest appointmentRequest)
{
    if(ModelState.IsValid)
    {
        // Process...
        return RedirectToAction("Confirmation");
    }
    return View(appointmentRequest);
}

The form looks like this:

@model MyDomain.Models.AppointmentRequest

@using(Html.BeginForm("RequestAppointment", "Appointment" FormMethod.Post))
{
    // This following line throws the exception:
    @Html.DropDownListFor(x => x.Stylist,
        Model.Stylists.Select(x => new SelectListItem{ Text = x.Name, Value = x.Name })))

    <input type="submit" value="Make Request" />
}

The drop down list is populated form with the correct text & values. But when the form is submitted, the exception is thrown. What's going on?

Stack Trace:

[ArgumentNullException: Value cannot be null.
Parameter name: source]
   System.Linq.Enumerable.Select(IEnumerable`1 source, Func`2 selector) +6396316
   ASP._Page_Views_Appointment_RequestAppointment_cshtml.Execute() in c:\Projects\OasisSalon\OasisSalon.Mvc\Views\Appointment\RequestAppointment.cshtml:9
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +280
   System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +104
   System.Web.WebPages.StartPage.ExecutePageHierarchy() +143
   System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +157
   System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +384
   System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19() +33
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +825460
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +265
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +825488
   System.Web.Mvc.Controller.ExecuteCore() +159
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +335
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +62
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +20
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +54
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +469
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +375

Upvotes: 0

Views: 2207

Answers (4)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038940

You must initialize the Stylists property in your POST action if you intend to redisplay the same view:

[HttpPost]
public ActionResult RequestAppointment(AppointmentRequest appointmentRequest)
{
    if(ModelState.IsValid)
    {
        // Process...
        return RedirectToAction("Confirmation");
    }

    appointmentRequest.Stylists = _repository.Stylists;
    return View(appointmentRequest);
}

You get a NRE because you are attempting to render a DropDownList in your view using Model.Stylists in your view but obviously this property is null after the POST action is executed as you never assigned it and its value is not populated automatically because all that's sent into the POST request is the selected value of the dropdown list (the Stylist property).

Upvotes: 1

ngm
ngm

Reputation: 7477

I guess what is happening here is that Stylists is null in your Post action. It is not being bound during model binding, as the drop down list is for Stylist, not Stylists.

You would need to rebuild the Stylists property before passing the appointmentRequest model to the view.

Upvotes: 1

Shyju
Shyju

Reputation: 218782

ASP.NET MVC does not have ViewState. So it can not keep the Values of DropDown list across postbacks like ASP.ENT Webforms does. So I guess, in HttpPost Action method, you are returning the appointmentRequest to the View but the Stylists Property is null. You probably needs to reload it before returning the appointmentRequest back to the view.

Upvotes: 1

SLaks
SLaks

Reputation: 887547

My psychic debugging skills tell me that you're returning View() from the POST action without creating a model.

Upvotes: 3

Related Questions