使用自定义功能覆盖 MVC 模型显示名称注释

我有以下方法从键值 XML 文件中读取数据。我传入一个键并返回一个我曾经在视图上显示的值。


public static class TextManager

{

    public static string GetValue(string key)

    {

        string returnVal = null; 

        XmlSerializer serializer = new XmlSerializer(typeof(Entries));

        string path = HttpContext.Current.Server.MapPath("/App_Data/text-key-value.xml");

        if (File.Exists(path))

        {

            Entries entries = (Entries)serializer.Deserialize(File.OpenRead(path));

            var entry = entries.Where(u => u.Key == key).FirstOrDefault();

            if (entry != null)

            {

                returnVal = entry.Value;

            }

        }

        return returnVal;

    }

}

基本上,我希望能够在我的模型类中使用此方法作为数据注释,它将直接从我的站点文本文件中提取并设置为显示名称属性。


例如我想替换


[Display(Name = "Reference Code")]

public string ReferenceCode { get; set; }

有了这个


[DisplaySiteText("ReferenceCodeKey")]

public string ReferenceCode { get; set; }

DisplaySiteText 会将字符串引用“ReferenceCodeKey”传递给 GetValue 方法,将引用归档到文件中,然后将标准显示名称属性设置为文件中的任何内容。


如何创建自己的自定义模型注释来执行此操作,我过去通过创建继承自 ValidationAttribute 的类来编写自定义验证注释,但我认为这在这种情况下不起作用。


泛舟湖上清波郎朗
浏览 134回答 3
3回答

白衣染霜花

DisplayNameAttribute您可以为此目的继承public class DisplaySiteTextAttribute : DisplayNameAttribute{    private string _key;    public DisplaySiteTextAttribute(string key)    {        _key = key;    }    public override string DisplayName    {        get        {            return TextManager.GetValue(_key);        }    }}

小怪兽爱吃肉

有多种选项可用于自定义模型元数据:自定义框架提供元数据的方式。(创建ModelMedatadaProvider)创建新的元数据属性。(实施IMetadataAware)修改现有属性。(派生现有属性。)第三个选项已在其他答案中讨论过。在这篇文章中,我将分享第一个和第二个选项。选项 1 - 自定义框架提供元数据的方式您可以更改获取显示文本的逻辑,而无需更改属性。事实上,它的责任是ModelMetaDataProvider获取模型的元数据,包括属性的显示文本。因此,作为一种选择,您可以保持Display属性不变,而是创建一个新的模型元数据提供程序并从不同的源返回属性元数据。为此,您可以通过派生自 来创建新的元数据提供程序DataAnnotationsModelMetadataProvider。然后重写GetMetadataForProperty并调用base,以获取元数据。然后DisplayName根据您的逻辑通过阅读文本管理器进行更改。您还需要注册新的元数据提供程序,如ModelMetadataProviders.Current中所示App_Start。using System;using System.ComponentModel;using System.ComponentModel.DataAnnotations;using System.Linq;using System.Web.Mvc;public class MyCustomModelMetadataProvider : DataAnnotationsModelMetadataProvider{    protected override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor,        Type containerType,        PropertyDescriptor propertyDescriptor)    {        var metadata = base.GetMetadataForProperty(modelAccessor,             containerType, propertyDescriptor);        var display = propertyDescriptor.Attributes            .OfType<DisplayAttribute>().FirstOrDefault();        if (display != null)        {            metadata.DisplayName = TextManager.GetValue(display.Name);        }        return metadata;    }}然后将其注册到Application_Start():ModelMetadataProviders.Current = new MyCustomModelMetadataProvider();当您想要更改为模型提供元数据的方式时,此方法非常有用。例如,当您想要从外部文件而不是资源加载显示名称和描述时,而不更改现有属性。选项 2 - 创建新的元数据属性创建元数据感知属性的另一个标准解决方案是创建属性并实现IMetadataAware接口。然后在实现中OnMetadataCreated您可以轻松设置 的属性metadata。这种方法不需要注册新的元数据提供者。此方法受默认元数据提供程序支持,对于创建新的元数据感知属性非常有用:using System;using System.Web.Mvc;public class CustomMetadataAttribure : Attribute, IMetadataAware{    public string Key { get; set; }    public CustomMetadataAttribure(string key) => this.Key = key;    public void OnMetadataCreated(ModelMetadata metadata)    {        metadata.DisplayName = TextManager.GetValue(this.Key);    }}当您想要扩展元数据属性并添加更多属性时,此方法非常有用。例如,当您想添加一些属性来控制渲染时。您可以设置ModelMetadata属性或向其AdditionalValues字典添加一些新值。

慕森卡

using System;using System.Web.Mvc;public class CustomMetadataAttribure : Attribute, IMetadataAware{&nbsp; &nbsp; public string Key { get; set; }&nbsp; &nbsp; public CustomMetadataAttribure(string key) => this.Key = key;&nbsp; &nbsp; public void OnMetadataCreated(ModelMetadata metadata)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; metadata.DisplayName = TextManager.GetValue(this.Key);&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP