首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向MVC ModelMetadata添加新属性

向MVC ModelMetadata添加新属性
EN

Stack Overflow用户
提问于 2014-04-03 09:59:53
回答 1查看 7.2K关注 0票数 4

我看到了一些替代的方法,比如AdditionalValues,但我想知道是否有可能在这样的场景中向模板视图中可用的ModelMetadata对象添加一个新属性。

例如,您可以拥有:

代码语言:javascript
复制
@ViewData.ModelMetadata.MvvmBound

我希望在编辑器和显示模板中使用它来将MVVM属性添加到正在呈现的HTML元素中。

我完全迷失了方向,但到目前为止,我的努力如下:

代码语言:javascript
复制
public class MyModelMetaDataProvider : DataAnnotationsModelMetadataProvider
{
    protected new MyModelMetaData CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
    {
        ModelMetadata modelMetaData = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
        MyModelMetaData myMetaData = (MyModelMetaData)modelMetaData;

        return myMetaData;
    }
}

public class MyModelMetaData: ModelMetadata
{
    public MyModelMetaData(ModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
        : base(provider, containerType, modelAccessor, modelType, propertyName)
    {

    }

    public int MyProperty { get; set; }
}  

然后在全局asax中我使用:

代码语言:javascript
复制
ModelMetadataProviders.Current =new MyModelMetaDataProvider();

问题是,如果我试图在视图中使用MyProperty,它就不会被识别,这是我预料到的,因为VS不知道定制的ModelMetadata类。

我甚至不确定这是否可能?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-04-03 11:53:48

AdditionalValues类中有一个字典ModelMetadataRef here

可以使用AdditionalMetadata属性向该字典添加值,如下所示:

代码语言:javascript
复制
public class DummyModel
{
    [AdditionalMetadata("MvvmBound", true)]
    public string PropertyA{ get; set; }

    public string PropertyB{ get; set; }
}

您可以在string编辑器模板中检查这些内容,例如:

代码语言:javascript
复制
@{
    bool isBound = false;
    if(ViewData.ModelMetadata.AdditionalValues.ContainsKey("MvvmBound"))
    {
        isBound = (bool)ViewData.ModelMetadata.AdditionalValues["MvvmBound"];    
    }
}

//use isBound to set some attributes in the html element

您还可能希望在DummyModel编辑器模板中检查这些属性,您可以按照以下方式检索单个属性的元数据:

代码语言:javascript
复制
@ModelMetadata.FromLambdaExpression(x => x.PropertyA, ViewData).AdditionalValues["MvvmBound"] 

这段代码有一些缺点。这种方法需要将键名传递给AdditionalValues字典,还需要将值从对象转换为正确的类型。您可以创建自己的扩展方法,以便从元数据中检索该值,而无需手动提供密钥名并手动执行转换:

代码语言:javascript
复制
public static class ModelMetadataExtensions
{
    public static bool IsMvvmBound(this ModelMetadata metadata)
    {
        if (!metadata.AdditionalValues.ContainsKey("MvvmBound")) return false;
        return (bool)metadata.AdditionalValues["MvvmBound"];
    }
}

这将使您在编辑器模板中有一个更干净的代码。例如,在上面的DummyModel编辑器模板中,您可以这样做(请记住将扩展名方法的命名空间添加到/Views文件夹中的Web.config文件中):

代码语言:javascript
复制
<h3>WholeModel Is MvvmBound?: @ViewData.ModelMetadata.IsMvvmBound()</h3>
<h3>PropertyA Is MvvmBound?: @ModelMetadata.FromLambdaExpression(x => x.PropertyA, ViewData).IsMvvmBound()</h3>
<h3>PropertyB Is MvvmBound?: @ModelMetadata.FromLambdaExpression(x => x.PropertyB, ViewData).IsMvvmBound()</h3>

可以将该扩展方法与扩展IMetadataAware的自定义属性配对,这样每次在属性上使用该扩展方法时,都不需要对元数据值的键名进行硬编码:

代码语言:javascript
复制
public class IsMvvmBoundAttribute : Attribute, IMetadataAware 
{
    public IsMvvmBoundAttribute()
    {
        this.IsMvvmBound = true;
    }

    public bool IsMvvmBound { get; set; }

    //This is the single method of IMetadataAware, and what allows us to add the values into the AdditionalValues dictionary
    public void OnMetadataCreated(ModelMetadata metadata)
    {
        metadata.AdditionalValues.Add("MvvmBound", this.IsMvvmBound);
    }
}

public class DummyModel
{
    //[AdditionalMetadata("MvvmBound", true)] <- replaced with the new attribute
    [IsMvvmBoundAttribute]
    public string PropertyA{ get; set; }

    public string PropertyB{ get; set; }
}

因为ModelMetadata.AdditionalValues是一个Dictionary<string,object>,所以不局限于每个键存储一个简单的值。您可以按照上面的代码创建包含所需所有属性的自己的类,一个属性,用于设置每个这些值,并将该类的实例保存到AdditionalValues字典中,以及从字典中提取该类实例的扩展方法。

正如您所看到的,您可以在不需要自己的ModelMetadata类或扩展ModelMetadataProvider的情况下走得很远。

希望能帮上忙!

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22834146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档