扩展方法不能正常工作

时间:2016-12-15 11:52:15

标签: c# asp.net asp.net-mvc

我目前正在开发一款使用C#和Asp.Net MVC开发的应用。

在其中一个视图中,我有大约10个DropDowns用户必须选择的视图。所选值存储在数据库中。

例如:

  1. DropDown Value 1Text显示为First Main Fault
  2. DropDown Value OneText显示为First Sub Fault
  3. 现在用户可以返回并编辑他们的记录。所以我想向他们展示已经选中的DropDown,其中包含存储在数据库中的值。

    为此,我使用以下扩展方法

    public static IEnumerable<SelectListItem> ToSelectListItems<T>(this IEnumerable<T> items, Func<T, string> textSelector, Func<T, string> valueSelector, Func<T, bool> selecter)
    {
       return items.OrderBy(item => textSelector(item))
          .Select(item =>
           new SelectListItem
           {
              Selected = selecter(item),
              Text = textSelector(item),
              Value = valueSelector(item)
            });
    }
    

    我称之为

    var mainFaultSelectedDdl = mainFaults.ToSelectListItems(
                m => m.MainFaultDescription,
                m => m.Id.ToString(),
                m => m.Id == mainFaultId); //mainFaultId here equals to 1. I've also tried m.Id.ToString() == mainFaultId.ToString() but still the same issue
    
    var subFaultSelectedDdl = subFaults.ToSelectListItems(
                s => s.SubFaultDescription,
                s => s.SubFaultDescription,
                s => s.SubFaultDescription == erst.SubFault); //erst.SubFault here equals to One
    

    当我调试代码时,我可以看到上述DropDowns Selected都设置为True,但在视图中未选择MainFault DropDown但已选择SubFault DropDown

    有人可以告诉我,我哪里出错了。

    这就是我目前在视图中生成DropDown的方式

    @Html.DropDownListFor(m => m.Serial.MainFault, Model.MainFaultDdl, "Please select a main fault", new { id = "mainFaults", @class = "form-control main-ddl" })
    @Html.DropDownListFor(m => m.Serial.SubFault, Model.SubFaultDdl, "Please select a sub fault", new { id = "subFaults", @class = "form-control main-ddl" })
    

1 个答案:

答案 0 :(得分:1)

模型绑定通过绑定到您的属性的值来工作,在您的情况下是Serial.MainFault的值。如果Serial.MainFault的值与选项值之一匹配(由Id中对象的mainFaults属性的值定义),则将选中它。如果它与某个值不匹配,那么将选择第一个选项,因为必须有。

使用Selected方法时,忽略设置SelectListItem DropDownListFor()属性,因为内部方法会自行构建IEnumerable<SelectListItem>并设置Selected属性关于你绑定的属性的值(请注意,如果在this answer中描述的循环中使用DropDownListFor()),则存在例外情况。

但是,您的扩展方法似乎没有必要,因为MVC已经有了使用SelectList构造函数之一构建IEnumerable<SelectListItem>的方法。

根据您显示的代码,您的GET方法可以简单地

var model = new YourModel();
model.Serial.MainFault = mainFaultId; // set the value to be displayed initially
model.MainFaultDdl = new SelectList(mainFaults, "Id", "MainFaultDescription"); // generate the options
return View(model);

或者您可以使用以下方法生成选项

model.MainFaultDdl = mainFaults.Select(x => new SelectListItem()
{
    Value = x.Id.ToString(),
    Text = x.MainFaultDescription
};

,视图中将显示正确的选项。