I have following problem. In my view model I defined some list properties as follows:
public class BasketAndOrderSearchCriteriaViewModel
{
List<KeyValuePair> currencies;
public ICollection<KeyValuePair> Currencies
{
get
{
if (this.currencies == null)
this.currencies = new List<KeyValuePair>();
return this.currencies;
}
}
List<KeyValuePair> deliverMethods;
public ICollection<KeyValuePair> DeliveryMethods
{
get
{
if (this.deliverMethods == null)
this.deliverMethods = new List<KeyValuePair>();
return this.deliverMethods;
}
}
}
This view model is embedded in another view model:
public class BasketAndOrderSearchViewModel
{
public BasketAndOrderSearchCriteriaViewModel Criteria
{
[System.Diagnostics.DebuggerStepThrough]
get { return this.criteria; }
}
}
I use 2 action methods; one is for the GET and the other for POST:
[HttpGet]
public ActionResult Search(BasketAndOrderSearchViewModel model){...}
[HttpPost]
public ActionResult SubmitSearch(BasketAndOrderSearchViewModel model){...}
In the view I implement the whole view model by using the EditorFor-Html Helper which does not want to automatically display DropDownLists for List properties!
1. Question: How can you let EditorFor display DropDownLists?
Since I could not figure out how to display DropDownLists by using EditorFor, I used the DropDownList Html helper and filled it through the view model as follows:
public IEnumerable<SelectListItem> DeliveryMethodAsSelectListItem()
{
List<SelectListItem> list = new List<SelectListItem>();
list.Add(new SelectListItem()
{
Selected = true,
Text = "<Choose Delivery method>",
Value = "0"
});
foreach (var item in this.DeliveryMethods)
{
list.Add(new SelectListItem()
{
Selected = false,
Text = item.Value,
Value = item.Key
});
}
return list;
}
My 2. question: As you can see I pass my view model to the action metho with POST attribute! Is there a way to get the selected value of a DropDownList get binded to the passed view model? At the moment all the DropDownList are empty and the selected value can only be fetched by the Request.Form which I definitely want to avoid!
I would greatly appreciate some ideas or tips on this!
Let’s try to take on this one:
Answer to Question 1: How can you let EditorFor display DropDownLists?
When you call
Html.EditorFor()you can pass extra ViewData values to the EdiorTemplate View:Now you have
ViewData["DeliveryMethods"]andViewData["Currencies"]initialized and available inside your EditorTemplate.In your
EditorTemplateyou somehow need to call and convert those entries into DropDowns / SelectLists.Assuming you’ve got an ascx file of type
System.Web.Mvc.ViewUserControl<BasketAndOrderSearchCriteriaViewModel>you could do the following:Same goes for the Currencies.
This setup will make your
DeliveryMethodAsSelectListItem()obsolete and you can use any kind of list. Means you are not bound to KeyValuePairs. You’ll just need to adjust your call onHtml.DropDownList()from now on.As you can see, I have introduced some new properties to your
BasketAndOrderSearchCriteriaViewModel:They are used to store the currently selected value.
Answer to Question 2: Is there a way to get the selected value of a DropDownList get binded to the passed view model?
In the EditorFor template we are passing the newly created
Model.SelectedDeliveryMethodandModel.SelectedCurrencyproperties as theSelectedValue Parameter(See 4th Overload of the DropDownList Extension Method).Now that we have the View doing it’s job: How can we get the currently selected value inside the POST Action?
This is really easy now:
Note: I don’t have an IDE to test it right now, but it should do the trick or at least show you in which direction to go.