加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 向MVC ModelMetadata添加新属性

发布时间:2020-12-16 03:59:35 所属栏目:asp.Net 来源:网络整理
导读:我正在看到其他方法,例如AdditionalValues,但我想知道是否有可能最终在一个场景中你可以向模板视图中可用的ModelMetadata对象添加新属性. 例如,您可以: @ViewData.ModelMetadata.MvvmBound 我想在编辑器和显示模板中使用它来将MVVM属性添加到正在呈现的HTML
我正在看到其他方法,例如AdditionalValues,但我想知道是否有可能最终在一个场景中你可以向模板视图中可用的ModelMetadata对象添加新属性.

例如,您可以:

@ViewData.ModelMetadata.MvvmBound

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

我完全迷失了,但到目前为止,这是我的努力:

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,string propertyName)
        : base(provider,propertyName)
    {

    }

    public int MyProperty { get; set; }
}

然后在全球的asax我使用:

ModelMetadataProviders.Current =new MyModelMetaDataProvider();

问题是如果我尝试在视图中使用MyProperty它无法识别,我预期,因为VS不知道自定义ModelMetadata类.

我甚至不确定这是可能的吗?

解决方法

ModelMetadata类中有一个字典AdditionalValues. Ref here

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

public class DummyModel
{
    [AdditionalMetadata("MvvmBound",true)]
    public string PropertyA{ get; set; }

    public string PropertyB{ get; set; }
}

你可以在字符串编辑器模板中检查它们,例如:

@{
    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的编辑器模板中检查这些属性,您可以在其中检索各个属性的元数据,如下所示:

@ModelMetadata.FromLambdaExpression(x => x.PropertyA,ViewData).AdditionalValues["MvvmBound"]

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

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文件中):

<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的自定义属性配对,这样您就不必在每次在属性上使用时对元数据值的键名称进行硬编码:

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的情况下走得很远.

希望能帮助到你!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读