我已经看到了许多类似的问题,但似乎没有一个答案能让我比我更进一步。
我有一个ViewModel,它包含一些表示特定库存UI控件并附加了一些验证逻辑的复杂类型。我需要将这些内容渲染到基于EditorTemplate / DisplayTemplate的页面,并且还需要在提交表单时正确绑定属性,以便开发人员可以在其控制器中使用视图模型等。
这方面的简单例子是
public class TestViewModel
{
public HierarchyField MyField {get; set; }
}
最简单的是,我需要开发人员能够通过简单的
为这个视图模型创建一个编辑器@Html.EditorForModel()
对于HierarchyField的任何可编辑部分,要在该类型的自定义EditorTemplate中设置字段。
通过使用自定义的MetaDataProvider并覆盖IsComplexType,我已经得到了允许这个渲染,虽然不是我完全熟悉的东西,但它确实可以完成这项工作。此解决方案的详细信息(http://blogs.msdn.com/b/stuartleeks/archive/2010/04/01/collections-and-asp-net-mvc-templated-helpers-part-3.aspx?Redirected=true)
我现在卡住尝试获取模型绑定以在提交表单时更新属性并调用HierarchyField类上的方法来执行一些自定义验证并根据该调用的结果更新ModelState。
我首先创建了一个DefaultModelBinder的子类,该子类在BindProperty覆盖中具有逻辑,以检查绑定的属性是否属于此类型。到目前为止都很好。当我想调用获取预期值的实例方法并尝试验证该值时出现问题。 BindProperty方法给了我一个PropertyDescriptor实例,它允许我找到关于我的属性的元数据,以及一个带有ValueProvider的BindingContext,它允许我读取值,但是,没有从我的复杂类型返回的实例:
bindingContext.ValueProvider.GetValue(propertyDescriptor.Name + ".Value")
其中propertyDescriptor.Name +“。Value”等同于我在EditorTemplate中有以下这样的事实:
@Html.TextBoxFor(model => model.Value)
而不是类型,因为我显然只在回发的字段中引用了Value属性,我得到一个String []。我假设,为了让它工作,我将需要为HierarchyField注册某种类型的ValueProvider,但理想情况下我正在寻找更通用的东西,因为我有许多这些类型要设置,所有其子类是一个常见的抽象类型(它们都有一个名为'Value'的属性,它返回其值的字符串表示形式)。
如果我是诚实的,整个过程看起来很痛苦,我觉得我错过了一些非常简单的事情。不幸的是,我确实需要这是通用的,因为有很多这些字段,我确实需要这个模型,或类似的字段来处理它们的验证,因为使用DataAnnotation验证属性无法做到这一点。我无法创建与特定视图模型绑定的自定义代码,我更愿意将与特定字段绑定的代码最小化,而更喜欢适用于基类(FieldBase)及其任何子类的内容。
如果有人需要查看附加代码,请尽快发布。
答案 0 :(得分:6)
我在一些项目中使用复杂类型和自定义渲染没有任何问题。也许我误解了你的问题,但我想我可以发布一个简化的工作示例(MVC4),也许它会在路上帮助你。
在我的例子中,复杂类型定义为:
[ComplexType]
public class AccessType
{
public bool ReadAccess { get; set; }
public bool EditAccess { get; set; }
}
模型定义为:
public class UserAccess
{
[Key]
public Int32 UserId { get; set; }
public AccessType AccessType { get; set; }
}
我在名为 AccessType.cshtml 的 Views \ Shared \ DisplayTemplates 中创建了以下显示模板,以处理复杂类型的呈现当它被显示时。
@model [path to complex type].AccessType
@Html.LabelFor(m => m.EditAccess,"Read access")
@Html.DisplayFor(m => m.ReadAccess)
@Html.LabelFor(m => m.EditAccess, "Edit access")
@Html.DisplayFor(m => m.EditAccess)
我在名为 AccessType.cshtml 的 Views \ Shared \ EditorTemplates 中创建了以下编辑模板,以处理复杂类型的呈现当它被编辑时。
@model [path to complex type].AccessType
@Html.LabelFor(m => m.ReadAccess,"Read access")
@Html.CheckBoxFor(m => m.ReadAccess)
@Html.LabelFor(m => m.EditAccess, "Edit access")
@Html.CheckBoxFor(m => m.EditAccess)
对于使用此复杂类型的模型的视图文件,我进行了以下更改:
对于 _CreateOrEdit.cshtml 文件,我添加了这一行来渲染复杂类型部分:
@Html.EditorFor(m => m.AccessType)
...到 Delete.cshtml 和 Details.cshtml 我已添加:
@Html.DisplayFor(m => m.AccessType)
...以及 Index.cshtml 我添加了:
@Html.DisplayFor(_ => item.AccessType)
这就是我需要渲染和使用复杂类型的全部内容。
如果您的问题更复杂,请添加一些代码来说明。