【问题标题】:MVC DropDownList with EditorTemplate showing Selected Value and invalid name field as propertyName.propertyName带有 EditorTemplate 的 MVC DropDownList 将所选值和无效名称字段显示为 propertyName.propertyName
【发布时间】:2013-10-04 16:45:40
【问题描述】:

我有一个通过 EditorTemplate 呈现的下拉列表。该属性在 Validation 类中有 UIHints 并正确显示,但是当我查看 HTML 时,控件的名称是 PropertyType.PropertyName 而不仅仅是 PropertyName。

这会阻止模型绑定。

我也无法将选定的值返回给视图。

我该如何解决这个问题?

更新详情请参阅下面的答案。

视图模型

public partial class HouseholdEditViewModel
{
    public int householdID { get; set; }
    public int familyID { get; set; }
    public string address { get; set; }
    public HousingTypeDropDownViewModel housingType { get; set; }
    public KeyworkerDropDownViewModel keyworker { get; set; }
    public string attachmentDate { get; set; }
    public bool loneParent { get; set; }
    public string familyPhoneCode { get; set; }
    public string familyPhone { get; set; }
}

下拉视图模型

public class HousingTypeDropDownViewModel
{
    public int housingTypeID { get; set; }
    public IEnumerable<SelectListItem> Items { get; set; }
}

编辑器模板

@model WhatWorks.ViewModels.HousingTypeDropDownViewModel

@Html.DropDownListFor(h => h.housingTypeID, new SelectList(Model.Items, "Value", "Text"))

查看

using (Html.ControlGroupFor(property.Name))
{                    
@Html.Label(property.GetLabel(), new { @class = "control-label" })
 <div class="controls">
         @Html.Editor(property.Name, new { @class = "input-xlarge" })
         @Html.ValidationMessage(property.Name, null, new { @class = "help-inline" })
 </div>
}

HTML

<div class="control-group">
    <label class="control-label" for="Housing_Type">Housing Type</label>                 
    <div class="controls">
        <select data-val="true" data-val-number="The field housingTypeID must be a number." data-val-required="The housingTypeID field is required." id="housingType_housingTypeID" name="housingType.housingTypeID">
            <option value="1">Owner Occupied</option>
            <option value="2">Rented - Social Landlord</option>
        </select>
        <span class="field-validation-valid help-inline" data-valmsg-for="housingType" data-valmsg-replace="true"></span>
    </div>
</div>

【问题讨论】:

    标签: c# html asp.net-mvc mvc-editor-templates


    【解决方案1】:

    对此进行了更多研究,看来这是按预期工作的。

    最简单的解决方法是在 EditorTemplate 中使用 DropDownList 而不是 DropDownListFor。将name 设置为空白字符串,Html.Editor 只获取一次属性名称。另请注意 Model.Items 更改为 SelectList

    @model WhatWorks.ViewModels.HousingTypeDropDownViewModel
    
    @Html.DropDownList("", Model.Items)
    

    为了进一步详细说明这一点,我尝试在我的 ViewModel 中使用 DropDownListIEnumerable&lt;SelectListItem&gt;,并且努力让我的 HTML 标记正确呈现。其中一部分涉及在我的编辑视图中需要Selected Value

    由于这似乎是一个常见问题,我稍微修改了这篇文章的标题,并将在此处记录控制器代码 - 这对我有用,可能不是最佳实践... Caveat Emptor!

    IRepository

    public interface IHouseholdRepository : IDisposable
    {
        IEnumerable<tHousehold> Get();
        tHousehold GetById(int Id);
        IEnumerable<SelectListItem> AddHousingType();
        IEnumerable<SelectListItem> EditHousingType(int id);
        //etc...
    
    }
    

    存储库

    public IEnumerable<SelectListItem> AddHousingType()
    {
        var query = from ht in context.tHousingType
                    orderby ht.housingType
                    select new
                    {
                        ht.housingTypeID,
                        ht.housingType
                    };
    
        return query.AsEnumerable()
            .Select(s => new SelectListItem
            {
                Value = s.housingTypeID.ToString(),
                Text = s.housingType
            });
    }
    
    public IEnumerable<SelectListItem> EditHousingType(int id)
    {
        var housingType = (from h in context.tHousehold
                          where h.householdID == id
                          select new
                              {
                                  h.tHousingStatus.FirstOrDefault().housingTypeID
                              }
                          );  
    
        var query = from ht in context.tHousingType
                    orderby ht.housingType
                    select new
                    {
                        ht.housingTypeID,
                        ht.housingType
                    };
    
        return query.AsEnumerable()
            .Select(s => new SelectListItem
               {
                   Value = s.housingTypeID.ToString(),
                   Text = s.housingType,
                   Selected = (housingType.FirstOrDefault().housingTypeID == s.housingTypeID ? true : false)
               });
    }
    

    控制器

        public ActionResult Edit(int id = 0)
        {
            HousingTypeDropDownViewModel housingType = new HousingTypeDropDownViewModel
            {
                Items = _repo.EditHousingType(id)
            };
    
            HouseholdEditViewModel h = GetUpdate(id);
            //GetUpdate is Automapper code unrelated to the DropDown 
    
            h.housingTypeID = housingType;
    
            if (h == null)
            {
                return HttpNotFound();
            }
            return View(h);
        }
    

    以上内容的灵感来自于太多的 SO 帖子,无法提及。谢谢大家,希望这对其他人有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-11
      相关资源
      最近更新 更多