Is it possible to set up the built-in asp-for
tag helper to take the input placeholder from the [Display(Prompt = "This is the placeholder")]
attribute in the view model.
[Display(Name="Name", Prompt = "This is the placeholder")]
public string Name { get; set; }
In MVC 5 I am able to achieve this by adding additional logic in my editor templates and checking the ViewData.ModelMetadata.Watermark
property. For example:
@model string
@{
Dictionary<string, object> htmlAttributes = new Dictionary<string, object>();
htmlAttributes.Add("class", "form-control");
if (!string.IsNullOrWhiteSpace(ViewData.ModelMetadata.Watermark))
{
htmlAttributes.Add("placeholder", ViewData.ModelMetadata.Watermark);
}
}
@Html.Label("")
@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, htmlAttributes)
@Html.ValidationMessage("", "", new { @class = "text-danger" })
But now in ASP.NET Core 1.0 I would like to start using the new tag helpers approach. By default, the build in asp-for
helper simply ignores the Prompt
attribute value.
Having my own custom implementation of the asp-for
attribute, e.g. my-asp-for
is an option and most probably I will end up having it for the sake of maintainability and reusing additional logic.
But then the Watermark
property is no longer present in the ModelMetadata
, i.e. there is no such thing as For.Metadata.Watermark
.
The only place I can see the Prompt
value in the asp-for
helper is somewhat hidden.
So I have two questions. Is there a smarter way to do that ? Is it a bad practice to take the placeholder from the viewmodel metadata, i.e. I should explicitly specify it it in the razor file ?
I have just done a quick test and if I understand you correctly, this appears to work out of the box for me with the default VS template:
Model:
public class LoginViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email", Prompt = "[email protected]")]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
View snippet:
<div class="form-group">
<label asp-for="Email" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
Result: