【问题标题】:How does the following code work in mvc3?以下代码如何在 mvc3 中工作?
【发布时间】:2013-06-05 04:46:01
【问题描述】:

我的控制器代码

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>

这些下拉列表是如何创建的?这对我来说不是很清楚。我想知道它是如何工作的。

【问题讨论】:

    标签: asp.net asp.net-mvc-3 razor


    【解决方案1】:

    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。与模型状态和验证的集成值得注意。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-18
      • 2017-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多