我已经看到了许多类似的问题,但似乎没有一个答案让我比我更进一步.
我有一个ViewModel,它包含一些复杂的类型,代表某些库存UI控件并附加了一些验证逻辑.我需要将这些内容渲染到基于EditorTemplate/DisplayTemplate的页面,并且还需要在提交表单时正确绑定属性,以便开发人员可以在其控制器中使用视图模型等.
这方面的简单例子是
public class TestViewModel
{
public HierarchyField MyField {get; set; }
}
Run Code Online (Sandbox Code Playgroud)
最简单的是,我需要开发人员能够用简单的方法为这个视图模型创建一个编辑器
@Html.EditorForModel()
Run Code Online (Sandbox Code Playgroud)
对于HierarchyField的任何可编辑部分,要在该类型的自定义EditorTemplate中设置字段.
通过使用自定义的MetaDataProvider并覆盖IsComplexType,我已经得到了允许这个渲染,虽然不是我完全熟悉的东西,但确实可以完成这项工作.这个解决方案的详细信息在这里(http://blogs.msdn.com/b/stuartleeks/archive/2010/04/01/collections-and-asp-net-mvc-templated-helpers-part-3.aspx?Rreirected =真)
我现在卡住尝试获取模型绑定以在提交表单时更新属性并调用HierarchyField类上的方法来执行一些自定义验证并根据该调用的结果更新ModelState.
我首先创建了一个DefaultModelBinder的子类,该子类在BindProperty覆盖中具有逻辑,以检查绑定的属性是否属于此类型.到目前为止都很好.当我想调用获取预期值的实例方法并尝试验证该值时出现问题.BindProperty方法为我提供了一个PropertyDescriptor实例,它允许我查找有关我的属性的元数据,以及一个带有ValueProvider的BindingContext,它允许我读取值,但是,没有从我的复杂类型返回的实例:
bindingContext.ValueProvider.GetValue(propertyDescriptor.Name + ".Value")
Run Code Online (Sandbox Code Playgroud)
其中propertyDescriptor.Name +".Value"等同于我在EditorTemplate中有以下事实:
@Html.TextBoxFor(model => model.Value)
Run Code Online (Sandbox Code Playgroud)
而不是类型,因为我显然只在回发的字段中引用了Value属性,我得到一个String [].我假设,为了让它工作,我将需要为HierarchyField注册某种类型的ValueProvider,但理想情况下我正在寻找更通用的东西,因为我有许多这些类型要设置,所有其子类是一个常见的抽象类型(它们都有一个名为'Value'的属性,它返回其值的字符串表示形式).
如果我诚实,整个过程看起来很痛苦,我觉得我错过了一些非常简单的事情.不幸的是,我确实需要这是通用的,因为有很多这些字段,我确实需要这个模型,或类似的字段来处理它们的验证,因为使用DataAnnotation验证属性无法做到这一点.我无法创建与特定视图模型绑定的自定义代码,我宁愿最小化与特定字段关联的代码,更喜欢适用于基类(FieldBase)及其任何子类的内容.
很高兴发布额外的代码,如果有人需要看到它.