Reputation: 17879
I want to create a custom DataAnnotations-Attribute for my editor as a clean and reuseable way to load the editor in a model like this:
class MyModel {
[MyEditor(ShowPreview: true)]
public string Text{ get; set; }
}
I found out that a custom attribute can be done by inherit from Attribute:
class MyEditorAttribute : Attribute { }
The problem is: How can I get information about the field like id or name (in this example Text) and how can I return my custom template when the html should get rendered in the view like
@Html.EditorFor(model => model.Text)
The only way I found out which works is using the UIHint-Attribute.
class MyModel {
[UIHint("MyEditor"), AllowHtml]
public string Text{ get; set; }
}
In this example I can add a view named Views/Shared/EditorTemplates/MyEditor.cshtml which gets automatically rendered for this attribute. There I can get for example the id of the field with ViewData.TemplateInfo.GetFullHtmlFieldId(string.Empty)
But I want to create a custom attribute because its cleaner, I can specify there some attributes for my editor in a clean way. How can I do this using DataAnnotations? I couldn't find information about this. I also searched for the source of the UIHint-Class to see how it works, but although the .NET framework is open source I can't find the source of those class.
Upvotes: 0
Views: 535
Reputation: 54618
I want to create a custom attribute because its cleaner, I can specify there some attributes for my editor in a clean way.
Yes you can do this.
How can I do this using DataAnnotations?
DataAnnotations is a namespace, don't confuse a name space with a class like attribute
. What you want is an Attribute
.
First create an attribute that derives from the UIHintAttribute
.
public UIDateTimeAttribute : UIHintAttribute
{
public UIDateTimeAttribute(bool canShowSeconds)
: base("UIDateTime", "MVC")
{
CanShowSeconds = canShowSeconds;
}
public bool CanShowSeconds { get; private set; }
}
Then apply it to a model:
public class Person
{
[UIDateTime(false)]
public DateTime Birthday { get; set; }
}
Then create your /Views/Shared/DisplayTemplates/UIDateTime.cshtml
file:
@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)
Upvotes: 2