【问题标题】:ASP.Net MVC view dropdownlist not being binded to model after submit (post)提交(发布)后,ASP.Net MVC 视图下拉列表未绑定到模型
【发布时间】:2011-01-02 23:27:04
【问题描述】:

我有一个用于创建视图的视图模型类,它由 2 个不同的属性类和一个选择项列表(用于下拉列表)组成。下拉列表和其中一类的字段始终显示在视图中,但仅在选择列表的特定选项时才显示第二类的字段。 (通过 jQuery 加载和返回部分视图的控制器,为第二类强类型)

第二类视图中的字段是一些普通的 input=text 字段和一个下拉列表。

当我提交表单时,所有数据都将正确绑定,除了第二类中列表的值。

问题是,如果出现验证错误,并且我返回带有模型的视图(以显示错误),那么下拉列表(第二类的下拉列表)是空的,因为没有办法选择从中,提交将始终具有 isValid=false :S

这是我如何设置的示例:

我目前有一个如下所示的视图模型:

public class ViewModel
{
   public GenericData genericData{get;set;}
   public SpecializedData specializedData {get;set;}
   public List<SelectListItem> types { get; set; }
}

public class GenericData
{
   public Type type {get;set;}
   public String name {get;set;}
   public String description{get;set;}
}
public class SpecializedData
{
   public String field{get;set;}
   public int foreignKey{get;set;}
   public List<SelectListItem> listOfForeignKeys{ get; set; }
}

视图是针对 ViewModel 的强类型,并以这种方式设置:

<p>
   <label for="genericData.type"> Type:  </label>
        <%=Html.DropDownList("genericData.type",Model.types, "Choose a type") %>
</p>
<p>
    <label for="genericData.name"> Name:</label>
    <%: Html.TextBox("genericData.name")%>
    <%= Html.ValidationMessage("genericData.name", "*")%>
</p>
//Same thing for Description as for name

<div id="SpecializedFields">
           //This will display the specialized info it was already captured before.
           <% if (Model.SpecializedData!= null && Model.GenericData.Type == "Specialized")
           {
               Html.RenderPartial("SpecializedInfoView", Model.specializedData);
           } %>
</div>
<p>
     <input type="submit" value="Create" />
</p>

$(document).ready(function () {
        $("#CatalogItem_Type").change(function () {

            var typeVal = $("#GenericData_type").val();
            if (typeVal == "specialized") {
                $("#SpecializedFields").load("/MyController/SpecializedFields");
            }

控制器会做这样的事情

public ActionResult SpecializedFields()
{
     List<SelectListItem> foreignIds = getForeignIdsFromDataBase();
     SpecializedData model = new SpecializedData ();
     model.listOfForeignIds = foreignIds;
     return PartialView("SpecializedInfoView",model);
}

最后,SpecialezedInfoView 是 SpecializedData 的强类型视图,类似于通用视图,如下所示:

<p>
   <label for="specializedData.foreignKey"> Key:  </label>    <%=Html.DropDownList("specializedData.foreignKey",Model.listOfForeignKeys, "Choose key") %>
</p>
<p>
    <label for="SpecializedData.field"> Field:</label>
    <%: Html.TextBox("specializedData.field")%>
    <%= Html.ValidationMessage("specializedData.field", "*")%>
</p>

当我点击提交时,如果它不是一个专门的项目,我将为specializedData 属性获得一个空值,这没关系。如果它是一个专门的项目,那么它不会为空,我会从genericData 中获取所有属性,我也会得到specializedData.fieldspecializedData.foreignKey 的值,但specialized.listOfForeignKeys 将是NULL 这意味着如果存在验证错误并且我使用当前模型返回视图,那么所有内容都将具有先前输入的值,但是 带有外键列表的 DropDownList 将为空 ,现在也没法选择id了。

我知道我可以检查接收帖子的方法中的specializedData 是否不为空,然后重新生成键列表并将其分配给当前模型(因为它是唯一丢失的数据) ,但这意味着必须进行额外的数据库调用,而不是模型中的信息!

我知道这是一个很长的问题,但我想明确说明我是如何设置的,有人知道为什么 listOfForeignKeys 在回发后没有被传回模型!?

谢谢!

【问题讨论】:

  • 你能简单描述一下这个问题吗?我无法理解这个问题。
  • 视图模型内的类中的 List 是我提交(发布)时唯一未绑定的字段
  • 请为您的 POST 操作方法添加源代码。

标签: c# asp.net-mvc data-binding c#-4.0


【解决方案1】:

我想通了...问题是 DropDownLists 的值在您绑定时不会发送回模型...但是,由于绑定会自动调用视图模型的构造函数 List&lt;SelectItemList&gt; Types 是在那里被填满并不是因为绑定。第二个列表未在构造函数中构建,因此它为空。我添加了查询以获取SpecializedData 构造函数中列表的信息,现在它可以工作了..

仍然有点糟糕的是,当用户点击帖子时,会额外调用数据库,如果出现验证错误,还会调用更多次。也许我会尝试做一个缓存来存储查询结果,但暂时就足够了。

谢谢!

【讨论】:

  • 为了避免这种情况,为什么不使用带有惰性初始化的静态集合作为列表的基础?
猜你喜欢
  • 2011-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多