3

私はポコクラスの製品を持っています

public class Product
{
    public int Id {get;set;}

    [RequiredEx]
    public string ProductName {get;set;}
}

RequiredEx 属性は RequiredAttribute (System.ComponentMode.DataAnnotations` の小さなラッパーではないため、毎回リソースの種類/名前を指定する必要はありません。

public class RequiredExAttribute : System.ComponentModel.DataAnnotations.RequiredAttribute
{
    public RequiredExAttribute()
    {
        this.ErrorMessageResourceType = typeof(ModelResources);
        this.ErrorMessageResourceName = "ErrorMessage.Required";
    }
}

ここで、プロパティを Display 属性で装飾したいと思います

[Display(ResourceType=typeof(ModelResources), Name="Product.ProductName")]
public string ProductName { get; set; }

この場合、シールされているため、DisplayAttribute から継承することはできません。ResourceType=typeof(ModelResources)この属性を使用するたびに入力する必要がなくなる可能性はありますか?

4

2 に答える 2

0

Nameのプロパティのみを使用している場合は、シールされていないDisplayAttribute(older) から継承することでこれを実現できます。DisplayNameAttribute

using System.Resources;

namespace System.ComponentModel
{
    public class LocalisedDisplayNameAttribute
        : DisplayNameAttribute
    {
        readonly ResourceManager m_resourceManager;
        readonly string          m_resourceName;

        public LocalisedDisplayNameAttribute(ResourceManager resourceManager,
                                             string          resourceName)
            : base()
        {
            m_resourceManager = resourceManager;
            m_resourceName    = resourceName;
        }

        public override string DisplayName
        {
            get { return m_resourceManager.GetString(m_resourceName); }
        }
    }
}

次に、共通文字列リソースの表示属性を設定できます。

public class DisplayBizAttribute
    : LocalisedDisplayNameAttribute
{
    public DisplayBizAttribute(string resourceName)
        : base(StringsBiz.ResourceManager, resourceName)
    {
    }
}

public class DisplayWebAttribute
    : LocalisedDisplayNameAttribute
{
    public DisplayBizAttribute(string resourceName)
        : base(StringsWeb.ResourceManager, resourceName)
    {
    }
}

次に、文字列リテラルまたは定数を使用して、プロパティの表示名を非常に簡単にローカライズできます。

[DisplayBiz("ProductName")]
public string ProductName { get; set; }

[DisplayBiz(StringNames.PHONE_NUMBER)]
public string ProductName { get; set; }

[DisplayWeb("EmailAddress")]
public string EmailAddress { get; set; }

アップデート

これは、各属性クラスで列挙型を宣言し、コンストラクターを変更するか、新しいコンストラクターを追加することで改善できます。

public class DisplayBizAttribute
    : LocalisedDisplayNameAttribute
{
    public enum Name
    {
        PhoneNumber,
        ProductName,
    }

    public DisplayBizAttribute(Name resourceName)
        : base(StringsBiz.ResourceManager, resourceName.ToString())
    {
    }
}

ハードコーディングされた文字列を使用する必要がなくなりました。

[DisplayBiz(DisplayBiz.Name.ProductName)]
public string ProductName { get; set; }

これはあなたがよく行うことなのでusing、列挙型を短縮するために a を追加したいと思います:

using Biz = System.ComponentModel.DisplayBiz.Name;
...
[DisplayBiz(Biz.PhoneNumber)]
public string PhoneNumber { get; set; }
于 2016-09-14T07:00:23.480 に答える