我的控制器代码
public ActionResult Create(string id)
{
ViewBag.ALLO_ID = new SelectList(_unitOfWork.AllocationMRepository.Get(), "ALLO_ID", "ALLO_ID", id);
ViewBag.TERR_ID = new SelectList(_unitOfWork.TerrListRepository.Get().OrderBy(m => m.TERR_ID), "TERR_ID", "TERR_ID");
ViewBag.ITEM_ID = new SelectList(_unitOfWork.SampleInfo.Get(), "ITEM_ID", "ITEM_ID");
return View();
}
在我看来
<div class="editor-field">
@Html.DropDownList("ALLO_ID", String.Empty)
@Html.ValidationMessageFor(model => model.ALLO_ID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.TERR_ID, "Territory Name")
</div>
<div class="editor-field">
@Html.DropDownList("TERR_ID", String.Empty)
@Html.ValidationMessageFor(model => model.TERR_ID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ITEM_ID, "Item Name")
</div>
<div class="editor-field">
@Html.DropDownList("ITEM_ID", String.Empty)
@Html.ValidationMessageFor(model => model.ITEM_ID)
</div>
如何创建这些下拉列表?这对我来说不是很清楚。我想知道它是如何工作的。这可能是一个废话问题,但我很想知道我是初学者。
先谢谢。
答案 0 :(得分:2)
Grab the source并在您的计算机上构建它。认真。我经常提到我的副本。
回答您的具体问题,即“框架如何创建下拉列表?”它正在迭代一个可枚举的集合并创建一个字符串。
MVC库为HtmlHelper
类定义了许多扩展方法。您可以轻松定义自己的。当然,您可以构建其他帮助程序类,但HtmlHelper
可用于此目的。
逐步完成几层重载,我们发现:
private IHtmlString BuildDropDownList(string name, string defaultOption, IEnumerable<SelectListItem> selectList,
object selectedValue, IDictionary<string, object> htmlAttributes) {
var modelState = ModelState[name];
if (modelState != null) {
selectedValue = selectedValue ?? ModelState[name].Value;
}
selectedValue = ConvertTo(selectedValue, typeof(string));
if (selectedValue != null) {
var newSelectList = new List<SelectListItem>(from item in selectList select new SelectListItem(item));
var comparer = StringComparer.InvariantCultureIgnoreCase;
var selectedItem = newSelectList.FirstOrDefault(item => item.Selected || comparer.Equals(item.Value ?? item.Text, selectedValue));
if (selectedItem != default(SelectListItem)) {
selectedItem.Selected = true;
selectList = newSelectList;
}
}
TagBuilder tagBuilder = new TagBuilder("select") {
InnerHtml = BuildListOptions(selectList, defaultOption)
};
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttribute("name", name, replaceExisting: true);
tagBuilder.GenerateId(name);
// If there are any errors for a named field, we add the css attribute.
AddErrorClass(tagBuilder, name);
return tagBuilder.ToHtmlString(TagRenderMode.Normal);
}
真的不是那么复杂。使用“For”后缀的扩展方法有点复杂。
@Html.LabelFor(model => model.TERR_ID, "Territory Name")
注意lambda表达式?框架实际上并不执行它;相反,它将其解析为元数据并使用它来获取项目的完全限定名称。然后,可以使用它从原始属性中检索各种信息,例如与验证有关的DataAnnotations
。
实施的关键在private static MvcHtmlString SelectInternal(...)
,包含在System.Web.Mvc.Html.SelectExtensions
中。与模型状态和验证的集成是值得注意的。