Missing parameter received in the controller when

2019-08-03 06:15发布

问题:

I have include some models in my asp.net mvc4 view so I have create a base view model which contains the two other models:

namespace MyNamespace.Models
{
    public class CustomViewModel
    {
        public FirstTypeModel FirstViewModel { get; set; }
        public SecondTypeModel SecondViewModel { get; set; }
    }
}

and the view:

 @model MyNamespace.Models.CustomViewModel

 @using (Html.BeginForm("AddFields", "Configure", FormMethod.Post))
 { 
         (...)
                 <div id="componentId">
                     @Html.LabelFor(m => m.FirstViewModel.SelectedCompTypeId, new { @id = "componentIdLabel" })
                     @Html.DropDownListFor(m => m.FirstViewModel.SelectedCompTypeId, Model.FirstViewModel.CompTypeItems, new { @name = "SelectedCompTypeId", @id = "componentType" })
                 </div>
         (...)

                 <input id="submitAddComp" type="submit" value="@Resource.ButtonTitleAddComponent" />

 }

in my controller:

public ActionResult AddFields(string param1, string param2, string param3, int selectedCompTypeId)
{
 ...
}

when click on the submit button I am getting selectedCompTypeId as null (param1, param2 and param3 are passed correctly), but if I watch below request from within the controller it has the correct value:

Request["FirstViewModel.SelectedCompTypeId"]

so how to pass the correct parameter to the controller in order to selectedCompTypeId not to be null?

Note: including only one model, before creating the base model which contains the others two, it was working correctly. Before, lamba expression was m => m.SelectedCompTypeId instead m => m.FirstViewModel.SelectedCompTypeId.

回答1:

Add a constructor initializing your first and second model.

namespace MyNamespace.Models
{
    public class CustomViewModel
    {
        public CustomViewModel()
        {
            FirstViewModel = new FirstTypeModel();
            SecondViewModel = new SecondTypeModel();
        }

        public FirstTypeModel FirstViewModel { get; set; }
        public SecondTypeModel SecondViewModel { get; set; }
    }
}

EDIT: But instead of passing all parameters one by one, just put the Model itself in your AddFields action. The problem you are facing, is that as you are using DropDownListFor the name of the parameter is "FirstViewModel.SelectedCompTypeId" and not just "SelectedCompTypeId" as you have it in your controller.

There are 2 options, one better than the other:

OPTION 1:

Instead of using

public ActionResult AddFields(string param1, string param2, string param3, int selectedCompTypeId)
{
 ...
}

use it this way

public ActionResult AddFields(CustomViewModel model)
{
 ...
}

this is better, because if you add more fields tomorrow, you don't need to change actions signature, and the binding is done by the framework.

OPTION 2: Change the DropDownListFor for a DropDownList, and this way, you can say which is the name of the parameter, and make it work. It is far preferrable the first option... is cleaner.

@Html.DropDownList("selectedCompTypeId", theList, "Select one...", new { @class = "myNiceCSSStyle"})