views:

696

answers:

5

I create a DropDown with the Html.DropDownList(string NameSelectListInViewData) method. This generates a valid Select input with the correct values. And all is well.

Upon submit however, the value in the source SelectList is not bound.

Case: ViewData.SearchBag.FamilyCodes:

public SelectList FamilyCodes { get; set; }

Html that generates the dropdown:

<%=Html.DropDownList("SearchBag.FamilyCodes")%>

Generated html:

<select id="SearchBag.FamilyCodes" name="SearchBag.FamilyCodes">
 <option value=" ">Any</option>
 <option value="A">BLUE</option>
 <option value="B">BLACK</option>
 <option value="C">BEIGE</option>
 <option value="G">GREEN</option>
 <option value="O">ORANGE</option>
 <option value="P">PURPLE</option>
 <option value="R">RED</option>
 <option value="S">GRAY</option>
 <option value="U">BROWN</option>
 <option value="W">WHITE</option>
 <option value="Y">YELLOW</option>
</select>

In my controller I have an action with a parameter searchBag.

public ActionResult AdvancedSearch(SearchBag searchBag) { 
    //Do Stuff with parameters in searchBag
    return View("AdvancedSearch", searchViewData);
}

All other fields bind just fine, only the selection boxes don't. Any ideas?

UPDATE
For future readers it might be worth it to read this blog post: http://haacked.com/archive/0001/01/01/model-binding-to-a-list.aspx

A: 

While "SearchBag.FamilyCodes" is a valid HTML id, the framework will attempt to map each form item to a corresponding parameter of the same name and you cannot have a period in a parameter name. If you assign a separate ID to the control (different overload of the Html.DropDownList method), does it come through?

GalacticCowboy
I gave the control a different (unique) ID but to no avail.I named all my other controls in the same way since their model is in ViewData.Model.SearchBag.[aName]Since the view is correctly showing all the fields, I guess the name of that field is correct. Not?
borisCallens
I double checked that by giving a different string to the Html.DropDownList() but an error confirmed that other strings didn't render to the correct model field.
borisCallens
I also tried putting my values directly under the model, to no avail. I don't think the dot is the problem
borisCallens
A: 

SearchBag needs to be lower case in the html (searchBag rather than SearchBag)

A: 

I think you need to change the type of FamilyCodes from SelectList to string.

public string FamilyCodes { get; set; }

Then on submit the value of FamilyCodes should be the value selected from the dropdown list. I have several of these in my current project and have no problems.

37Stars
That is indeed working and is how I do it at some places. But it doesn't give me the advantage of the automatic modelbinding from the framework. Furthermore, what happens in the selectlist is multiselect?
borisCallens
A: 

I am running into the same issue, but with a multiselect. Boris, was there any resolution to this? Or should I skip model binding and work with the FormCollection object that gets passed to my controller method?

Joe
Hi Joe, you might want to check out this blog post:http://haacked.com/archive/0001/01/01/model-binding-to-a-list.aspxI currently have slightly changed my Model partly to solve this problem and partly for business logic reasons. I'm still not really happy with how it's working, but I don't have better suggestions either.
borisCallens
A: 

Had a similar issue yesterday with select lists, the list would generate fine, just that on UpdateModel- would fail =- not bound?

And i found the answer in the parameters list...

SelectList (
Collection - items to use in the  drop down,
ValueField - ie the primarykey as a String,
NameField  - ie the name of the thing as a String,
SelectedValue -  which is the passed in current objects FK relationship)

So for me ...

Country = new SelectList(db.Countries, "pkCountry", "CountryName",address.fkCountry);

I use the ViewModel approach - and have this in the constructor of the view Model...

public AddressCountryViewModel(){
public SelectList Countrys {get; private set;}
public AddressCountryViewModel(Address address)
{
     Countrys = new SelectList(db.Countries, "pkCountry", "CountryName",address.fkCountry);
}

I then grab the values in the controllers Edit Action and assign back to the object that is updating...

address.fkCountry = Convert.ToInt32(collection["fkCountry"]);
Because the SelectList is really only usefull in a scenario to create a dropdown, I feel it doesn't belong anywhere else. I pass on a regular list and create the SelectList in the view. This has the disadvantage of more C# in my view however. So it basically is a matter of preference.
borisCallens
Hi Boris - this is done to prevent the additional hidden fields that are need to bind the model back to the underlying Model. You linked to the Hackked article and there are lots of hidden fields -which are there for the model referential integrity... my way you dont need them.