这是我的情况 -
我有两个嵌套的视图模型:
<%=Html.EditorFor(x => x.DisplayEntitiesWithRadioboxesViewModel)%><br />
位于其父级(StructureViewModel)中,我可以轻松填充嵌套的ViewModel并将其传递给主视图:
在控制器内 - 示例
var moveDepartment = new StructureViewModel();
moveDepartment.DisplayEntitiesWithRadioboxesViewModel = fullDepartmentList.Select(x => new DisplayEntityViewModel
{
Id = x.Id,
Path = x.Path,
PathLevel = x.PathLevel,
Description = x.Description,
});
return View(moveDepartment);
编辑完成 - 示例
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Site.Areas.Administration.ViewModel.DisplayEntityViewModel>>" %>
<table class="aligncenter"><%
if (Model != null)
{
foreach (var entity in Model)
{%>
<tr class="tRow">
<td style="text-align:left; text-indent:<%=Html.Encode(entity.PathLevel)%>em">
<%=Html.Encode(entity.Description)%>
<%=Html.RadioButton("radiobutton",entity.Id)%>
</td>
</tr><%
}
}%>
</table>
namespace Site.Areas.Administration.ViewModel
{
public class DisplayEntityViewModel
{
public int Id { get; set; }
public string Path { get; set; }
public string PathLevel { get; set; }
public string Description { get; set; }
}
}
但是,当我尝试撤回此信息时,嵌套的ViewModel为null:
[HttpPost]
public ActionResult Move(StructureViewModel StructureViewModel)
当我将鼠标悬停在StructureViewModel
上时,它只包含在父ViewModel中设置的数据。例如:可以看到隐藏值,但DisplayEntitiesWithRadioboxesViewModel = null。
我知道如何访问DisplayEntitiesWithRadioboxesViewModel
的唯一方法是使用FormCollection
并迭代FormCollection
并从嵌套的ViewModel中提取我需要的信息。
然而,这似乎不正确,因为我在我发现然后必须使用DisplayEntitiesWithRadioboxesViewModel
中的值重新填充FormCollection
,例如,如果发生了错误,则用户需要被发送回相同的视图。
我尝试过搜索网页/书籍但找不到解决方案。
有更好的方法吗?
提前感谢您的帮助。
为什么你使用EditorFor来做一个 简单的下拉,很容易 与DropDownFor一起使用
现在已经改变为使用DropDownFor。
什么是关键 DisplayEntitiesWithRadioboxesViewModel FormCollection中的值
{string[3]}
[0] = "DisplayEntitiesWithRadioboxesViewModel.radiobutton"
[1] = "Action"
[2] = "OldParentId"
克莱尔: - )
答案 0 :(得分:3)
一旦你理解了它的工作原理,你的问题很常见并且很容易修复。
现在您有一个视图模型,其属性为IEnumerable<T>
(与通用参数无关)。您正尝试将项目传递给视图,并在响应返回时使用相同的值填充IEnumerable<T>
,使用最初写入页面的值,并使用所选项目进行扩充(至少从您的代码中添加)无论如何已发布,这将有助于你在问题中陈述你的确切意图)。您遇到的问题是您必须以可以返回的方式将这些值发送到页面。
现在让我说你可能应该不使用这种技术。通常,最好只返回选择并在需要服务器端时再次生成列表。
从事物的外观来看,您希望返回整个列表,然后查找所选项目,即在下拉列表或单选按钮组之后。为了获得选择,控制器操作的参数必须具有与传回的变量匹配的属性。在这种情况下,您看起来对所有单选按钮使用参数名称radiobutton
(同样适用于下拉列表,只有它使用列表的名称)。选择哪一个,与该名称相关联的值将以该名称返回。 MVC框架负责尝试找到具有尽可能多的名称的适当操作。
您需要为action参数使用的是一个新类,它包含要提交回服务器的所有字段名称的属性!或者您当然可以简单地将radiobutton
属性添加到StructureViewModel
。实际上,您会注意到它已经尝试设置该值,只有它在视图模型上当前不存在。但是你仍然不会收到原始列表,但那没关系,因为即使你确实收到了原始列表,你也没有标识符可以让你知道选择了哪个项目!
希望这可以帮助您了解正在发生的事情,如果您有更多问题,请询问。
答案 1 :(得分:3)
我建议您在任何地方使用强类型助手,这样您就不必担心命名控件了。以下是如何继续:
型号:
public class DisplayEntityViewModel
{
public int Id { get; set; }
public string Path { get; set; }
public string PathLevel { get; set; }
public string Description { get; set; }
}
public class StructureViewModel
{
public IEnumerable<DisplayEntityViewModel> DisplayEntitiesWithRadioboxesViewModel { get; set; }
}
控制器:
public class HomeController : Controller
{
public ActionResult Index()
{
var moveDepartment = new StructureViewModel();
moveDepartment.DisplayEntitiesWithRadioboxesViewModel = new[]
{
new DisplayEntityViewModel
{
Id = 1,
Path = "some path 1",
PathLevel = "some path level 1",
Description = "some description 1"
},
new DisplayEntityViewModel
{
Id = 2,
Path = "some path 2",
PathLevel = "some path level 2",
Description = "some description 2"
},
};
return View(moveDepartment);
}
[HttpPost]
public ActionResult Index(StructureViewModel StructureViewModel)
{
return View(StructureViewModel);
}
}
主视图(~/Views/Home/Index.aspx
):
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<SomeNs.Models.StructureViewModel>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm()) { %>
<table class="aligncenter">
<%= Html.EditorFor(x => x.DisplayEntitiesWithRadioboxesViewModel) %>
</table>
<input type="submit" value="Go" />
<% } %>
</asp:Content>
编辑模板(~/Views/Home/EditorTemplates/DisplayEntityViewModel.ascx
)
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ToDD.Models.DisplayEntityViewModel>" %>
<tr class="tRow">
<td style="text-align:left; text-indent:<%=Html.Encode(Model.PathLevel)%>em">
<%= Html.Encode(Model.Description) %>
<!-- Remember that you need to place input fields for each property
that you expect to get back in the submit action
-->
<%= Html.HiddenFor(x => x.Description) %>
<%= Html.TextBoxFor(x => x.Path) %>
</td>
</tr>
现在提交表单,所有内容都应该正确绑定。需要注意的一点是,编辑器模板的强类型为DisplayEntityViewModel
,而不是IEnumerable<DisplayEntityViewModel>
。在主视图中,您可以写下:
<%= Html.EditorFor(x => x.DisplayEntitiesWithRadioboxesViewModel) %>
框架会自动检测属性是否为集合,并将为此集合的每个项目调用编辑器模板,因此您不再需要遍历使代码更优雅的元素。
更新:
使用下拉列表也非常简单:结帐this answer。
答案 2 :(得分:0)
你能告诉我EditorFor
看起来如何吗?为什么使用EditorFor
进行简单的下拉菜单,这很容易与DropDownFor
一起使用。
Key
DisplayEntitiesWithRadioboxesViewModel
值的FormCollection
是多少?
如果我理解正确,你有一个视图,有一些父信息,同时在同一视图中这两个字段的多次迭代。是吗?
然后我知道如何解决这个问题。