다음은 구현 예입니다.
public class MyMetadataProvider : DataAnnotationsModelMetadataProvider
{
protected override ModelMetadata CreateMetadata(
IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName
)
{
var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
var displayFor = attributes.OfType<DisplayForAttribute>().FirstOrDefault();
if (displayFor != null)
{
metadata.AdditionalValues.Add("RequiredRole", displayFor.Role);
}
return metadata;
}
}
Application_Start
에 등록됩니다 :
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
ModelMetadataProviders.Current = new MyMetadataProvider();
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DisplayForAttribute : Attribute
{
public DisplayForAttribute(string role)
{
Role = role;
}
public string Role { get; private set; }
}
다음이 속성을 사용하는 사용자 정의 메타 데이터 공급자를 작성할 수의 사용자가 다음과 같은 속성을 정의했다고 가정하자
이고 마지막 부분은 문자열 유형 (~/Views/Shared/EditorTemplates/String.cshtml
)에 대한 사용자 정의 편집기 템플릿을 작성하는 것입니다 :
@{
var visible = false;
if (ViewData.ModelMetadata.AdditionalValues.ContainsKey("RequiredRole"))
{
var role = (string)ViewData.ModelMetadata.AdditionalValues["RequiredRole"];
visible = User.IsInRole(role);
}
}
@if (visible)
{
@Html.TextBox(
"",
ViewData.TemplateInfo.FormattedModelValue,
new { @class = "text-box single-line" }
)
}
그리고 마지막으로는 속성 사용 :
public class MyViewModel
{
[DisplayFor("Admin")]
public string Name { get; set; }
}
및 뷰에서 :
@using (Html.BeginForm())
{
@Html.EditorFor(model => model.Name)
<input type="submit" value="OK" />
}
는 분명히 이것은 단지 문자열 편집기 템플릿을 포함하지만, 예를 쉽게 다른 확장 될 수있다 default templates에는 디스플레이 템플릿도 포함됩니다.
굉장한 구조와 구현! – nttakr
@Darin,이 작업을 수행 할 수 없습니다. 'return metadata' 문에 중단 점을 두는 것으로 모든 것이 훌륭해 보입니다. 메타 데이터에 대한 모든 추가 값과 기타 조정 사항이 있습니다. 그러나 View가로드 될 때까지 ViewModel.ModelMetaData에는 내 CustomProvider MetaData가 포함되어 있지 않습니다. –
@Doug Chamberlain, 당신은'DisplayForAttribute' 속성으로 장식 된 속성을위한 편집기 템플릿 안에서 이것을하고 있습니까? 예제에서와 같이, 기본'String.cshtml' 편집기 템플릿을 오버라이드하고 있습니다. –