validationrazor-pagesserver-sidemodelstatetag-helpers

TagHelper not working with server side Validations


Ok this is my problem. Today I decided to implement a mechanism that would make it easier for me to implement fields in the views. I have a project in razor pages and I do the validation of required fields on the server side. For example, in the page Model I have the following validation:

if (string.IsNullOrEmpty(Record.Name))
                ModelState.AddModelError(key: "Record.Name", errorMessage: RS_Relationships.name_field_required);

And this was the way I was building the field:

<div class="form-group mx-2 my-2 w-full sm:w-1/2 md:w-1/3 lg:w-1/4">
            <label asp-for="Record.Name" class="block"></label>
            <input asp-for="Record.Name" class="form-input w-full bg-yellow-100 dark:bg-yellow-100 dark:text-black"/>
            <span asp-validation-for="Record.Name" class="text-red-600"></span>
        </div>

This worked perfectly fine for me.

But by implementing the following tag helper, the span simply no longer displays the error message that the name field is required.

[HtmlTargetElement(tag: "text-required-field")]
public class StringRequiredFieldHelper : TagHelper
{
    [HtmlAttributeName("asp-for")]
    public ModelExpression? For { get; set; }
    
    [HtmlAttributeName("asp-validation-for")]
    public ModelExpression? Validation { get; set; }
    
    [HtmlAttributeName("label-for")]
    public string? LabelName { get; set; }
    
    public override void Process(TagHelperContext Context, TagHelperOutput Output)
    {
        var container = new TagBuilder("div");
        
        var label = new TagBuilder(tagName: "label");
        label.Attributes["for"] = For?.Name;
        label.AddCssClass("block");
        label.InnerHtml.Append(LabelName?.ToString() ?? string.Empty);
        
        var input = new TagBuilder(tagName: "input");
        input.Attributes["name"] = For?.Name;
        input.Attributes["id"] = For?.Name;
        input.Attributes["value"] = For?.Model?.ToString();
        input.AddCssClass("form-input w-full bg-yellow-100 dark:bg-yellow-100 dark:text-black");
        input.Attributes["type"] = "text";

        var validation = new TagBuilder(tagName: "span");
        validation.AddCssClass("text-red-600 field-validation-error");
        validation.Attributes["data-valmsg-for"] = Validation?.Name;
        validation.Attributes["data-valmsg-replace"] = "true";
        
        container.InnerHtml.AppendHtml(content: label);
        container.InnerHtml.AppendHtml(content: input);
        container.InnerHtml.AppendHtml(content: validation);
        Output.Content.SetHtmlContent(htmlContent: container);
    }
}

Field:

<text-required-field asp-for="Record.Name" asp-validation-for="Record.Name" label-for="@RS_Relationships.name"></text-required-field>

Can someone help me to solve this error?

After: enter image description here

Before: enter image description here


Solution

  • Solved.

    Simple solution, you only need to implement this validation into the tagHelper:

    var modelState = ViewContext?.ViewData.ModelState;
        if (modelState != null
            && For != null
            && modelState.TryGetValue(For.Name, out ModelStateEntry? entry)
            && entry.Errors.Count > 0)
        {
            validation.InnerHtml.Append(unencoded: entry.Errors[0].ErrorMessage);
        }