Reputation: 32202
I have a simple model:
public class MyViewModel {
public MyCustomType EmailAddress {get; set; }
}
In a certain view, I need to present an input box to allow editing of this property. Ideally I want to keep using the standard @Html.EditorFor
syntax, so I've created a /Views/Shared/EditorTemplates/MyCustomType.cshtml
template:
@model MyNamespace.MyCustomType
@Html.TextBoxFor(m => m.SomeStringProperty, new { @class = "form-control" })
I also have a custom IModelBinder
to read this input back into MyCustomType
when it's submitted, this all works fine.
However, as you can see from the property name, this property contains an Email address. I'd like to use the standard data annotations attributes to mark it as such, and then update MyCustomType.cshtml
to make use of it to render an <input type="email">
input box when necessary - not all uses of MyCustomType
are email addresses, hence wanting to use the standard attributes to mark it as such. When I do so:
public class MyViewModel {
[EmailAddress]
public MyCustomType EmailAddress {get; set; }
}
My custom template is no longer used - it instead reverts back to using the standard EditorFor
code, and essentially just displays the .ToString()
version of MyCustomType
inside an <input>
, rather than my custom editor template which pulls out a specific property.
Is there a way to make it use my custom editor template functionality, while still only requiring models to add the standard data annotations attributes?
Upvotes: 0
Views: 621
Reputation: 239290
Data annotations always take precedence over the type when it comes to editor templates. You have a few options:
Create a custom "EmailAddress" attribute. Technically, I think you could pretty much just subclass EmailAddressAttribute
without actually adding anything additional. The name of your custom attribute, though, would allow you to have a different editor template for that.
Go ahead and use the EmailAddress.cshtml
editor template, but branch inside. Assuming MyCustomType
inherits from String
:
@model String
@if (Model is MyCustomType)
{
...
}
else
{
...
}
Probably the easiest method, though, is to simply specify the template. It's not quite as automatic, but it doesn't require any additional work:
@Html.EditorFor(m => m.EmailAddress, "MyCustomType")
Which would then load MyCustomType.cshtml
instead of the default EmailAddress.cshtml
.
Upvotes: 2