यह एक पुराना प्रश्न है, लेकिन मुझे लगता है कि यह एक बहुत ही सामान्य समस्या है, और यहाँ MVC 3 में मेरा समाधान है।
सबसे पहले, गंदा तार से बचने के लिए स्थिरांक उत्पन्न करने के लिए एक टी 4 टेम्पलेट की आवश्यकता होती है। हमारे पास एक संसाधन फ़ाइल है 'Labels.resx' में सभी लेबल स्ट्रिंग्स हैं। इसलिए T4 टेम्पलेट सीधे संसाधन फ़ाइल का उपयोग करता है,
<#@ template debug="True" hostspecific="True" language="C#" #>
<#@ output extension=".cs" #>
<#@ Assembly Name="C:\Project\trunk\Resources\bin\Development\Resources.dll" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Globalization" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Resources" #>
<#
var resourceStrings = new List<string>();
var manager = Resources.Labels.ResourceManager;
IDictionaryEnumerator enumerator = manager.GetResourceSet(CultureInfo.CurrentCulture, true, true)
.GetEnumerator();
while (enumerator.MoveNext())
{
resourceStrings.Add(enumerator.Key.ToString());
}
#>
// This file is generated automatically. Do NOT modify any content inside.
namespace Lib.Const{
public static class LabelNames{
<#
foreach (String label in resourceStrings){
#>
public const string <#=label#> = "<#=label#>";
<#
}
#>
}
}
फिर, 'DisplayName' को स्थानीय बनाने के लिए एक एक्सटेंशन विधि बनाई जाती है;
using System.ComponentModel.DataAnnotations;
using Resources;
namespace Web.Extensions.ValidationAttributes
{
public static class ValidationAttributeHelper
{
public static ValidationContext LocalizeDisplayName(this ValidationContext context)
{
context.DisplayName = Labels.ResourceManager.GetString(context.DisplayName) ?? context.DisplayName;
return context;
}
}
}
'DisplayName' विशेषता को 'Labels.resx' से स्वचालित रूप से पढ़ने के लिए 'DisplayLabel' विशेषता द्वारा प्रतिस्थापित किया जाता है,
namespace Web.Extensions.ValidationAttributes
{
public class DisplayLabelAttribute :System.ComponentModel.DisplayNameAttribute
{
private readonly string _propertyLabel;
public DisplayLabelAttribute(string propertyLabel)
{
_propertyLabel = propertyLabel;
}
public override string DisplayName
{
get
{
return _propertyLabel;
}
}
}
}
उन सभी तैयारी के काम के बाद, उन डिफ़ॉल्ट सत्यापन विशेषताओं को छूने का समय। मैं उदाहरण के रूप में 'आवश्यक' विशेषता का उपयोग कर रहा हूं,
using System.ComponentModel.DataAnnotations;
using Resources;
namespace Web.Extensions.ValidationAttributes
{
public class RequiredAttribute : System.ComponentModel.DataAnnotations.RequiredAttribute
{
public RequiredAttribute()
{
ErrorMessageResourceType = typeof (Errors);
ErrorMessageResourceName = "Required";
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return base.IsValid(value, validationContext.LocalizeDisplayName());
}
}
}
अब, हम उन विशेषताओं को अपने मॉडल में लागू कर सकते हैं,
using Web.Extensions.ValidationAttributes;
namespace Web.Areas.Foo.Models
{
public class Person
{
[DisplayLabel(Lib.Const.LabelNames.HowOldAreYou)]
public int Age { get; set; }
[Required]
public string Name { get; set; }
}
}
डिफ़ॉल्ट रूप से, संपत्ति का नाम 'Label.resx' देखने के लिए कुंजी के रूप में उपयोग किया जाता है, लेकिन यदि आप इसे 'DisplayLabel' के माध्यम से सेट करते हैं, तो यह इसके बजाय इसका उपयोग करेगा।