You can bind a model-defined single reference to an ASP.NET MVC drop-down list by exposing a pick list and using the generated external-ID property; this page is for developers using code-generated ViewModels in MVC.
A combobox, pick list, and drop-down list are different names for the same selection pattern. Use one to set a single reference between objects when the number of choices is small enough to present as a list. For general combobox behaviour and troubleshooting, see Documentation:The combobox.
What the ViewModel must expose
For a single reference such as Example2.Example1, the MVC view needs four things:
| ViewModel member | Purpose | Example |
|---|---|---|
| Reference property | Holds the selected business object in the online ViewModel. | Example1
|
| Pick-list collection | Supplies the selectable objects. | Example1_PickList
|
| Pick-list presentation | Supplies the text displayed for each selectable object and an identity value for that object. | Identity and Presentation
|
| External-ID property | Carries the selected object's identity through MVC model binding and the HTTP postback. | Example1_AsExternalId
|
The generated Example1_AsExternalId member is the important MVC-specific part. MVC posts a value from the <select>; the external ID lets the ViewModel apply that posted selection back to the reference.
Define the pick list in MDriven Designer
- Create or edit the ViewModel that presents the object to edit. In this example, the ViewModel is
VMExample2and it exposes theExample1reference. - Add a pick list for the reference. MDriven Designer identifies a single link such as
Example1as a combobox candidate; you can use the right-click automation to create the related ViewModel members. - Review the proposed pick-list expression. MDriven Designer may suggest
Example1.allinstances. Change the expression when the choices must be filtered or sorted. - For example, order the choices by an attribute with an expression such as
Example1.allinstances->orderby(e|e.attribute1). - Define the pick-list presentation class. It must include an identity column and a presentation column. The identity is used as the HTML option value; the presentation is the text that the user sees.
- Decide in the ViewModel Editor whether and how the pick list represents a null reference. This determines whether the user can select no value.
- Ensure that code generation is enabled for the ViewModel, then generate code.
After generation, inspect the generated ViewModel API. In addition to the reference and pick-list collection, it should contain the generated external-ID property, for example Example1_AsExternalId.
Render the MVC drop-down list
Use Html.DropDownListFor to bind the control to the generated external-ID property. Supply the pick-list collection and the names of its identity and presentation members.
<div class="display-field">
@Html.DropDownListFor(
x => x.Example1_AsExternalId,
new SelectList(
Model.Example1_PickList, // selectable items
"Identity", // option value
"Presentation", // option text
Model.Example1_AsExternalId)) // selected value
</div>
<div class="display-field">
@Html.EditorFor(model => model.OwnedBy)
</div>
In this example, OwnedBy is rendered only to show other ViewModel data. The drop-down itself binds to Example1_AsExternalId, not directly to Example1.
Match the member names
The strings "Identity" and "Presentation" must match the members on the pick-list presentation objects. If your presentation class uses different member names, use those names in SelectList.
Apply the posted values
Use the standard offline-to-online ViewModel update pattern. The controller resolves the edited object's external ID, creates an online ViewModel, applies the posted offline ViewModel values, and commits the change.
[HttpPost]
public ActionResult Details(string Identity, VMExample2 offlinevm)
{
Example2 e2 = EcoSpace.ExternalIds.ObjectForId(Identity).AsObject as Example2;
try
{
VMExample2 onlinevm = VMExample2.Create(EcoSpace, e2);
ViewModelHelper.ApplyValues(offlinevm, onlinevm, null);
Commit();
return View("Details", onlinevm);
}
catch
{
return View("Details", offlinevm);
}
}
No combobox-specific code is required in this action. ViewModelHelper.ApplyValues applies the posted Example1_AsExternalId value to the online ViewModel, including the selected reference. This pattern also limits updates to the data exposed by the ViewModel. For the broader MVC update pattern and constraint handling, see Documentation:MVC View Model constraints.
Prevent a lost or incorrect selection
A combobox can appear to lose its selected value, or show the wrong value when the page opens, when the selected object is not in the pick-list collection.
Make the current value part of the collection used by the control. For example, if a filtered list excludes the currently assigned Example1, add that current object to the collection before rendering the view.
The collection must also be stable over time. Comboboxes work with objects, not only values. A collection can contain apparently identical data but still contain newly reconstructed objects, which can break selection matching. When the list is known and stable, create it for the EcoSpace and reuse it for as long as appropriate; storing it in the database can also be appropriate.
When not to use this pattern
Do not use a single-select drop-down to choose many objects or to present complex values. Use one of the multiple-selection widgets in custom controls in ViewModel-aided views instead.
If the choices are fixed strings rather than object references, use the string-specific approach in HowTos:Create Comboboxes with Strings.
