我需要扩展Html.Editor()
,以便根据模型中的某些属性生成HTML。例如:
public class Person
{
public string Name { get; set; }
[DisplayFor(Role.Admin)]
public string Surname { get; set; }
}
在这种情况下,如果用户与admin不同,生成的HTML将不会显示在View
中。
答案 0 :(得分:2)
这是一个示例实现。假设您已定义以下属性:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DisplayForAttribute : Attribute
{
public DisplayForAttribute(string role)
{
Role = role;
}
public string Role { get; private set; }
}
接下来,您可以编写一个使用此属性的自定义元数据提供程序:
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();
}
最后一部分是为String类型(~/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,包括显示模板。
答案 1 :(得分:0)
我的项目中有相同的内容,但代码正在运行。
我为ModelMetadata
或/和PropertyInfo
public static bool IsVisibleForRole( this PropertyInfo property, User c);
在我的Object.ascx中:
for ( var field in fields ) {
if(!field.IsVisibleForRole(this.CurrentUser())) continue;
//...
}
但是,在您的情况下,您可能不会跳过该字段,而是插入<input type="hidden">
。但这可能是安全问题。有关详细信息,请查看:http://www.codethinked.com/aspnet-mvc-think-before-you-bind