実行時に設定されるが、文字列フォーマットを使用するリソースファイルからの文字列に基づく、かみそりビューの動的ラベルを持つモデルが必要です。
単一のプロパティを持つ単純なモデルがあるとしましょう
public class Simple
{
[Display(ResourceType = (typeof(Global)), Name = "UI_Property1")]
[Required(ErrorMessageResourceType = (typeof(Global)), ErrorMessageResourceName = "ERROR_Required")]
[StringLength(40, ErrorMessageResourceType = (typeof(Global)), ErrorMessageResourceName = "ERROR_MaxLength")]
public string Property1{ get; set; }
}
そして、リソースファイルには次の文字列があります
UI_Property1 {0}
ERROR_Required Field {0} is required.
ERROR_MaxLength Maximum length of {0} is {1}
かみそりのビューでこのようなことをしたいです
@Html.LabelFor(m => m.Property1, "xyz", new { @class = "control-label col-sm-4" })
結果のビューには、フィールドラベルが「xyz」として表示され、値「xyz」もサーバーモデルの検証から返される検証メッセージに表示されます。
私はこれを運がなくて行うさまざまな方法を検討してきました。DisplayAttributeのオーバーライドを調査しましたが、これは封印されたクラスです。
DisplayName属性のオーバーライドも確認しましたが、これは必要な検証メッセージで正しく取得されません。さらに、属性コンストラクターで実行する必要があると思われる属性に動的テキストを挿入する方法がわかりませんでした。
カスタムDataAnnotationsModelMetadataProviderの作成も検討しましたが、これを使用して目的を達成する方法がわかりません。これは私のコーディングスキルの欠如によるものかもしれません。
'xyz'文字列は、web.configファイルの設定から取得され、LabelForコマンドで挿入する必要はありませんが、より意味がある場合は別の場所に挿入できます。
誰かが私がこれをどのように達成することができるかについて私に手がかりを与えることができればそれは素晴らしいことです。
この投稿を見つけました
DataAnnotationsModelMetadataProviderを置き換えて、返されたModelMetadataを操作することは有効ですか?
それは私を次のような解決策に導きました:
Web設定にカスタムセクションを追加しました
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="labelTranslations" type="AttributeTesting.Config.LabelTranslatorSection" />
... other sections here
</configSections>
<labelTranslations>
<labels>
<add label=":Customer:" translateTo="Customer Name" />
<add label=":Portfolio:" translateTo="Portfolio Name" />
<add label=":Site:" translateTo="Site Name" />
</labels>
</labelTranslations>
カスタムセクションを処理するためのクラスは、翻訳されるラベルをロードします
public class LabelElement : ConfigurationElement
{
private const string LABEL = "label";
private const string TRANSLATE_TO = "translateTo";
[ConfigurationProperty(LABEL, IsKey = true, IsRequired = true)]
public string Label
{
get { return (string)this[LABEL]; }
set { this[LABEL] = value; }
}
[ConfigurationProperty(TRANSLATE_TO, IsRequired = true)]
public string TranslateTo
{
get { return (string)this[TRANSLATE_TO]; }
set { this[TRANSLATE_TO] = value; }
}
}
[ConfigurationCollection(typeof(LabelElement))]
public class LabelElementCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new LabelElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((LabelElement)element).Label;
}
public LabelElement this[string key]
{
get
{
return this.OfType<LabelElement>().FirstOrDefault(item => item.Label == key);
}
}
}
public class LabelTranslatorSection : ConfigurationSection
{
private const string LABELS = "labels";
[ConfigurationProperty(LABELS, IsDefaultCollection = true)]
public LabelElementCollection Labels
{
get { return (LabelElementCollection)this[LABELS]; }
set { this[LABELS] = value; }
}
}
次に、翻訳者はカスタムセクションを使用して、特定のラベルが存在する場合は翻訳済みバージョンに翻訳し、存在しない場合はラベルを返します。
public static class Translator
{
private readonly static LabelTranslatorSection config =
ConfigurationManager.GetSection("labelTranslations") as LabelTranslatorSection;
public static string Translate(string label)
{
return config.Labels[label] != null ? config.Labels[label].TranslateTo : label;
}
}
次に、翻訳されたバージョンに基づいて表示名を変更するカスタムメタデータプロバイダーを作成しました
public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(
IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName)
{
// Call the base method and obtain a metadata object.
var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
if (containerType != null)
{
// Obtain informations to query the translator.
//var objectName = containerType.FullName;
var displayName = metadata.GetDisplayName();
// Update the metadata from the translator
metadata.DisplayName = Translator.Translate(displayName);
}
return metadata;
}
}
その後、すべてが正常に機能し、ラベルと検証メッセージはすべて翻訳されたバージョンを使用しました。標準のLabelForヘルパーを変更せずに使用しました。
リソースファイルは次のようになります
ERROR_MaxLength {0} can be no more than {1} characters long
ERROR_Required {0} is a required field
UI_CustomerName :Customer:
UI_PortfolioName :Portfolio:
UI_SiteName :Site:
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加