自定义数据注释 - 类似UIHint的属性

时间:2015-10-15 19:40:05

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

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

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

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

class MyEditorAttribute : Attribute { }

问题是:如何获取有关字段或名称的信息(在此示例中为文本),以及如何在视图中呈现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框架是开源的,但我找不到这些类的来源。

1 个答案:

答案 0 :(得分:2)

  

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

是的,你可以这样做。

  

如何使用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)