它是提供给CreateMetadata方法的参数之一(如果扩展元数据支持,则会覆盖它).
ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor, <<--THIS ONE
Type modelType,
string propertyName)
Run Code Online (Sandbox Code Playgroud)
我曾假设它允许您访问模型对象本身(例如,基于模型值设置元数据),但是当我尝试使用它来转换为我的模型对象时,我只是得到null.
Entity ent = (Entity)modelAccessor(); // = Null
Run Code Online (Sandbox Code Playgroud)
如果我误解了,有人可以解释它的目的是什么吗?或者,如何正确使用它?
谢谢
我们最初将其作为"对象模型",而不是"Func modelAccessor".我们不得不在MVC 2的船舶周期中改变它.
目的是延迟检索模型的实际值,直到您知道您将需要它为止(即,直到您调用ModelMetadata.Model).
它解决的问题实际上是一个相当深奥的问题,它涉及到LINQ to SQL类的模型绑定,其中包含一个外键引用.问题是,如果您检索到由外键关系表示的子对象(通常意味着该对象的延迟加载),则不再允许您通过设置外键来选择新的子对象身份证.在模型绑定时模拟绑定外键ID(而不是整个外键实体)是很常见的,但是如果我们检索了外键实体对象(为了填充ModelMetadata类)那么该绑定将不再是合法的,实际上是一个例外.由于ModelMetadata用于模型的两个方向 - 入站,通过模型绑定和出站,
modelAccessor 参数并不指向对象的实例,而是一个将访问对象的某些属性的函数。Func “封装了一个没有参数的方法,并返回由 TResult 参数指定的类型的值”。例如,如果我们有以下课程:
public class Bar(){
[DisplayName("I am Foo.")]
public string Foo{get;}
}
Run Code Online (Sandbox Code Playgroud)
当调用 CreateMetaData 时,它将为 Foo 属性创建元数据,而 modelAccessor 将是一个返回 Foo 值的函数。
我做了一些挖掘,找到了一种获取对象实例的方法,但它需要使用反射。在我的示例中,您可以执行以下操作来获取 Bar 类:
if (modelAccessor != null)
{
//Use reflection to get the private field that holds the Bar object.
FieldInfo container = modelAccessor.Target.GetType().GetField("container");
//Invoke field on the modelAccessor target to get the instance of the Bar object.
Bar myObject = (Bar)container.GetValue(modelAccessor.Target);
}
Run Code Online (Sandbox Code Playgroud)
我只针对一个简单的测试用例运行了这个,所以您的里程可能会有所不同,但希望这将有助于澄清正在发生的事情。
| 归档时间: |
|
| 查看次数: |
1644 次 |
| 最近记录: |