【问题标题】:Custom DataAnnotations-Attribute like UIHint自定义 DataAnnotations-Attribute,如 UIHint
【发布时间】:2015-10-15 19:40:05
【问题描述】:

我想为我的编辑器创建一个自定义的 DataAnnotations-Attribute,作为在这样的模型中加载编辑器的一种干净且可重用的方式:

class MyModel {
    [MyEditor(ShowPreview: true)]
    public string Text{ get; set; }
}

我发现自定义属性可以通过继承属性来完成:

class MyEditorAttribute : Attribute { }

问题是:如何获取有关字段的信息,例如 id 或名称(在此示例中为 Text),以及当 html 应该在视图中呈现时如何返回我的自定义模板,例如

@Html.EditorFor(model => model.Text)

我发现有效的唯一方法是使用 UIHint-Attribute。

class MyModel {
    [UIHint("MyEditor"), AllowHtml]
    public string Text{ get; set; }
}

在此示例中,我可以添加一个名为 Views/Shared/EditorTemplates/MyEditor.cshtml 的视图,该视图会自动为该属性呈现。在那里我可以得到例如带有ViewData.TemplateInfo.GetFullHtmlFieldId(string.Empty)的字段ID

但我想创建一个自定义属性,因为它更简洁,我可以以一种简洁的方式为我的编辑器指定一些属性。如何使用 DataAnnotations 做到这一点?我找不到这方面的信息。我还搜索了 UIHint-Class 的源代码以了解它是如何工作的,但是尽管 .NET 框架是开源的,但我找不到这些类的源代码。

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-mvc-5 data-annotations custom-attributes


    【解决方案1】:

    我想创建一个自定义属性,因为它更简洁,我可以以一种简洁的方式为我的编辑器指定一些属性。

    是的,你可以这样做。

    如何使用 DataAnnotations 做到这一点?

    DataAnnotations 是一个命名空间,不要将命名空间与attribute 之类的类混淆。你想要的是Attribute

    首先创建一个派生自UIHintAttribute 的属性。

    public UIDateTimeAttribute : UIHintAttribute
    {
      public UIDateTimeAttribute(bool canShowSeconds)
        : base("UIDateTime", "MVC")
      {
        CanShowSeconds = canShowSeconds;
      }
    
      public bool CanShowSeconds { get; private set; }
    }
    

    然后将其应用于模型:

    public class Person
    {
      [UIDateTime(false)]
      public DateTime Birthday { get; set; }
    }
    

    然后创建您的/Views/Shared/DisplayTemplates/UIDateTime.cshtml 文件:

    @model DateTime
    
    @{
      var format = "dd-MM-yy hh:mm:ss";
    
      // Get the container model (Person for example)
      var attribute = ViewData.ModelMetadata.ContainerType
        // Get the property we are displaying for (Birthday)
        .GetProperty(ViewData.ModelMetadata.PropertyName)
        // Get all attributes of type UIDateTimeAttribute
        .GetCustomAttributes(typeof(UIDateTimeAttribute))
        // Cast the result as UIDateTimeAttribute
        .Select(a => a as UIDateTimeAttribute)
        // Get the first one or null
        .FirstOrDefault(a => a != null);
    
      if (attribute != null && !attribute.CanShowSeconds)
      {
        format = "dd-MM-yy hh:mm";
      }
    }
    
    @Model.ToString(format)
    

    【讨论】:

    • 我也想过这种方式,可惜好像不能改变视图的路径,这样在不同项目之间共享编辑器就好了。
    • 您想将属性赋予很多responsibility。路径是目录的属性,RazorViewEngine 使用它来定位视图。 UIHint 只是一种注释这个属性应该使用其他视图(没有路径)的方法。
    • 问题是该属性是在另一个程序集中定义的,以便在多重应用程序中重用编辑器。要对视图执行此操作,我使用RazorGenerator。但是我需要指定完整路径。您的示例不适用于该示例,我在构造函数中使用路径的多个变体进行了尝试。但是在像@Html.Partial("/Views/Editor.cshtml") 这样的完整路径之外,它的工作,所以这个问题似乎与UIHint 有关。这就是我想要一个完整的自定义属性的原因。
    • 没有不起作用的代码,我无能为力。
    • 我用这个答案创建了自动完成 UIHint 属性miroprocessordev.blogspot.com/2016/08/…
    猜你喜欢
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多