MaxLength annotation to maxlength input property
asp.net-core, asp.net-core-mvc, c#, validation
Solution
You may need to implement this functionality via a TagHelper which can read this attribute and add it to the element when rendered, as the default `asp-for` one won't handle this.
Extending the Input TagHelper
Try declaring a TagHelper as follows within your project, which will etend the existing `asp-for` helper and handle reading any existing attributes / metadata and appending the necessary attributes to the element:
namespace YourProject.TagHelpers
{
[HtmlTargetElement("input", Attributes = "asp-for")]
public class MaxLengthTagHelper : TagHelper
{
public override int Order { get; } = 999;
[HtmlAttributeName("asp-for")]
public ModelExpression For { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
base.Process(context, output);
// Process only if 'maxlength' attr is not present
if (context.AllAttributes["maxlength"] == null)
{
// Attempt to check for a MaxLength annotation
var maxLength = GetMaxLength(For.ModelExplorer.Metadata.ValidatorMetadata);
if (maxLength > 0)
{
output.Attributes.Add("maxlength", maxLength);
}
}
}
private static int GetMaxLength(IReadOnlyList<object> validatorMetadata)
{
for (var i = 0; i < validatorMetadata.Count; i++)
{
var stringLengthAttribute = validatorMetadata[i] as StringLengthAttribute;
if (stringLengthAttribute != null && stringLengthAttribute.MaximumLength > 0)
{
return stringLengthAttribute.MaximumLength;
}
var maxLengthAttribute = validatorMetadata[i] as MaxLengthAttribute;
if (maxLengthAttribute != null && maxLengthAttribute.Length > 0)
{
return maxLengthAttribute.Length;
}
}
return 0;
}
}
}
Using The TagHelper
Then add a reference to it, either directly in your specific view, or globally in the `_ViewImports.cshtml` file as seen below:
@using YourProject
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, YourProject
Once added, this extended TagHelper should automatically decorate your element with the appropriate `maxlength` attribute, if present on your property:
<!-- Input -->
<label asp-for="PostCode"></label>
<input style="font-weight: normal;" class="form-control" placeholder="Post Code" asp-for="PostCode" data-val="true" autofocus />
<!-- Rendered -->
<label for="PostCode">Post Code</label>
<input style="font-weight: normal;" class="form-control" placeholder="Post Code" data-val="true" autofocus="" type="text" data-val-maxlength="Maximum number of characters that can be entered is 8!" data-val-maxlength-max="8" id="PostCode" name="PostCode" value="" maxlength="8">
Problem
Using the following DataAnnotations in ASP.NET Core 1.1. It would be good to have the max length of the input in my MVC View to be set to restrict the users input. Model ``` [Display(Name = "Post Code")] [MaxLength(8, ErrorMessage = "Maximum number of characters that can be entered is 8!")] public string PostCode { get; set; } ``` View ``` <label asp-for="PostCode"></label> <input style="font-weight: normal;" class="form-control" placeholder="Post Code" asp-for="PostCode" data-val="true" autofocus /> ``` renders as ``` <input style="font-weight: normal;" class="form-control valid" placeholder="Post Code" data-val="true" autofocus="" type="text" data-val-maxlength="Maximum number of characters that can be entered is 8!" data-val-maxlength-max="8" id="PostCode" name="PostCode" value="" wtx-context="FA5749C8-68AC-44FE-88B9-4BBDF9D48DAE" aria-invalid="false" aria-describedby="PostCode-error"> ``` I am wanting to generate the maxlength attribute from my class data annotation as per the below. (scroll to end); ``` <input style="font-weight: normal;" class="form-control valid" placeholder="Post Code" data-val="true" autofocus="" type="text" data-val-maxlength="Maximum number of characters that can be entered is 8!" data-val-maxlength-max="8" id="PostCode" name="PostCode" value="" wtx-context="FA5749C8-68AC-44FE-88B9-4BBDF9D48DAE" aria-invalid="false" aria-describedby="PostCode-error" maxlength="8"> ``` Appreciate any advice.