动态属性的Asp.Net MVC 3编辑器

我们一直试图让编辑模板与动态属性一起工作 – 无济于事。 也许你们中的一个可以帮助我们。

这大致是我们的课程:

public class Criterion { ... public string Text { get; set; } public dynamic Value { get; set; } public Type Type { get; set; } ... } 

我们的剃刀视图获得了一个包含一系列部分的模型,每个部分都包含一个标准列表。 (我们在运行时获得这些信息。)所有这些标准都应该以编辑模式显示 – 关于它们的实际类型:(摘录)

 @for (int i = 0; i < model.Sections.Count(); i++) { for (int j = 0; j < model.Sections[i].Criteria.Count(); j++) { var criterion = model.Sections[i].Criteria[j]; var type = criterion.Type.Name; var name = "Sections[" + i + "].Criteria[" + j + "].Value"; var criterionDisplayName = criterion.Text;  @Html.Editor(name, type) } } 

这确实显示了一个正确的复选框,但它没有使用该值来正确设置复选框状态(如果criterion.Value为true则检查)。 其他类型也是如此,例如ints 。 (它确实在POST请求后填写表单,但这是因为MVC使用临时模型来重新创建用户输入。)

我们已经尝试过并研究过:甚至可以将Editor模板与属性类型的属性一起使用? 如果是的话 – 我们怎样才能让它发挥作用? (我们不希望根据可能的类型来识别。我们希望MVC框架根据实际类型使用正确的编辑器模板。)

动态不适合ASP.NET MVC。 他们让我想起了ViewBag ,我讨厌从我身体深层织物ViewBag 。 所以我会采取不同的方法。

我们以下面的模型为例:

 public class Criterion { public string Text { get; set; } public object Value { get; set; } } 

值可以是您希望处理的任何类型。

现在你可以有一个控制器来填充这个模型:

 public class HomeController : Controller { public ActionResult Index() { var model = new[] { new Criterion { Text = "some integer", Value = 2 }, new Criterion { Text = "some boolean", Value = true }, new Criterion { Text = "some string", Value = "foo" }, }; return View(model); } } 

然后是相应的视图:

 @model IList @using (Html.BeginForm()) { for (int i = 0; i < Model.Count; i++) { 
@Html.LabelFor(x => x[i], Model[i].Text) @Html.EditorFor(x => x[i].Value, "Criterion_" + Model[i].Value.GetType().Name)
} }

现在,对于您要处理的每种类型,您可以定义相应的编辑器模板:

~/Views/Shared/EditorTemplates/Criterion_String.cshtml

 @model string @Html.TextBoxFor(x => x) 

~/Views/Shared/EditorTemplates/Criterion_Boolean.cshtml

 @model bool @Html.CheckBoxFor(x => x) 

~/Views/Shared/EditorTemplates/Criterion_Int32.cshtml

 @model int @{ var items = Enumerable .Range(1, 5) .Select(x => new SelectListItem { Value = x.ToString(), Text = "item " + x }); } @Html.DropDownListFor(x => x, new SelectList(items, "Value", "Text", Model)) 

显然,在视图中显示此模型只是第一步。 我想您需要获取用户在POST控制器操作中输入的值以进行某些处理。 在这种情况下,一些小的调整是必要的。 我们需要添加一个自定义模型绑定器,它能够在运行时实例化正确的类型,并将具体类型包含为每行的隐藏字段。 我已经在this post展示了一个例子。 另请注意,在此示例中,我使用了基类,而不是直接使用object类型。