首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扩展Html.Editor()

扩展Html.Editor()
EN

Stack Overflow用户
提问于 2011-03-26 22:26:57
回答 2查看 1.6K关注 0票数 1

我需要扩展超文本标记语言,以便根据模型中的一些属性来生成Html.Editor()。示例:

代码语言:javascript
复制
public class Person
{
    public string Name { get; set; }

    [DisplayFor(Role.Admin)]
    public string Surname { get; set; }
}

在这种情况下,如果用户与管理员不同,则生成的超文本标记语言将不会显示在View中。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-27 01:13:28

下面是一个示例实现。让我们假设您已经定义了以下属性:

代码语言:javascript
复制
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DisplayForAttribute : Attribute
{
    public DisplayForAttribute(string role)
    {
        Role = role;
    }
    public string Role { get; private set; }
}

接下来,您可以编写一个自定义元数据提供程序,该提供程序将使用此属性:

代码语言:javascript
复制
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中注册的

代码语言:javascript
复制
protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    ModelMetadataProviders.Current = new MyMetadataProvider();
}

最后一部分是为String类型(~/Views/Shared/EditorTemplates/String.cshtml)编写一个自定义编辑器模板:

代码语言:javascript
复制
@{
    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" }
    )
}

最后使用属性:

代码语言:javascript
复制
public class MyViewModel
{
    [DisplayFor("Admin")]
    public string Name { get; set; }
}

在视图中:

代码语言:javascript
复制
@using (Html.BeginForm())
{
    @Html.EditorFor(model => model.Name)
    <input type="submit" value="OK" />
}

显然,这只涵盖了字符串编辑器模板,但是这个示例可以很容易地扩展到其他default templates,包括显示模板。

票数 2
EN

Stack Overflow用户

发布于 2011-03-26 22:54:49

我在我的项目中有相同的东西,但代码正在工作。

我为ModelMetadata或/和PropertyInfo编写了一个扩展方法

代码语言:javascript
复制
public static bool IsVisibleForRole( this PropertyInfo property, User c);

在我的Object.ascx中:

代码语言:javascript
复制
for ( var field in fields ) {
     if(!field.IsVisibleForRole(this.CurrentUser())) continue;
     //...
}

不过,在您的示例中,您可能不会跳过该字段,而是插入一个<input type="hidden">。但这可能是安全问题。有关详细信息,请查看:http://www.codethinked.com/aspnet-mvc-think-before-you-bind

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5442931

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档