これを機能させる方法を見つけようとしているときに、DataAnnotations フレームワークの現在の化身では Description も Watermark も使用できないというブログ投稿に出くわしました。
おおよそ次のような回避策を思いつきました。
(免責事項: このコードは、構成によって構築されたメタデータ プロバイダーから削除するために、私のコンパイル バージョンから編集されているため、修正しないと直接コンパイルできない可能性があります。)
public class CustomDataAnnotationsModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(IEnumerable<System.Attribute> attributes, System.Type containerType, System.Func<object> modelAccessor, System.Type modelType, string propertyName)
{
var baseModelMetadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
var result = new CustomMetadata(modelMetadataProvider, containerType, modelAccessor, modelType, propertyName, attributes.OfType<DisplayColumnAttribute>().FirstOrDefault(), attributes)
{
TemplateHint = !string.IsNullOrEmpty(templateName) ? templateName : baseModelMetaData.TemplateHint,
HideSurroundingHtml = baseModelMetaData.HideSurroundingHtml,
DataTypeName = baseModelMetaData.DataTypeName,
IsReadOnly = baseModelMetaData.IsReadOnly,
NullDisplayText = baseModelMetaData.NullDisplayText,
DisplayFormatString = baseModelMetaData.DisplayFormatString,
ConvertEmptyStringToNull = baseModelMetaData.ConvertEmptyStringToNull,
EditFormatString = baseModelMetaData.EditFormatString,
ShowForDisplay = baseModelMetaData.ShowForDisplay,
ShowForEdit = baseModelMetaData.ShowForEdit,
DisplayName = baseModelMetaData.DisplayName
};
return result;
}
}
public class CustomMetadata : DataAnnotationsModelMetadata
{
private string _description;
public CustomMetadata(DataAnnotationsModelMetadataProvider provider, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName, DisplayColumnAttribute displayColumnAttribute, IEnumerable<Attribute> attributes)
: base(provider, containerType, modelAccessor, modelType, propertyName, displayColumnAttribute)
{
var descAttr = attributes.OfType<DescriptionAttribute>().SingleOrDefault();
_description = descAttr != null ? descAttr.Description : "";
}
// here's the really important part
public override string Description
{
get
{
return _description;
}
set
{
_description = value;
}
}
}
次に、Application_Start の Global.asax またはモデル メタデータ プロバイダーを登録する場所で、次のようにします。
ModelMetadataProviders.Current = new CustomMetadataProvider();