You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Validation TagHelper:修改Kendo DatePicker子Input类实现服务端验证

问题:给Kendo DatePicker的子Input添加服务端验证错误类

我尝试用TagHelper实现服务端验证,目标是给Kendo DatePicker生成的子input标签添加is-invalid类,但现有代码只会修改外层span的类。试过GetChildContentAsync但没成功,相关代码和输出如下:

现有TagHelper代码

[HtmlTargetElement("kendo-datepicker")]
[HtmlTargetElement("select")]
[HtmlTargetElement("input")]
public class ValidationErrorClassTagHelper : TagHelper
{
    [HtmlAttributeNotBound]
    [ViewContext]
    public ViewContext ViewContext { get; set; }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        if (context.TagName == "kendo-datepicker")
        {
            TagHelperAttribute taghelperAttribute = context.AllAttributes["for"];
            if (taghelperAttribute != null)
            {
                ModelExpression modelExpression = (ModelExpression)taghelperAttribute.Value;
                ViewContext.ViewData.ModelState.TryGetValue(modelExpression.Name, out ModelStateEntry entry);

                if (entry != null && entry.Errors.Any())
                {
                    output.Attributes.SetAttribute("class", "form-control " + "is-invalid");
                }
            }
        }
    }
}

当前错误HTML输出

<span class="k-datepicker k-input form-control is-invalid k-input-solid k-input-md k-rounded-md" style="">
  <input class="form-control k-input-inner valid" required="" data-val="true" data-val-required="Enter the date observed." id="ADR_Date" name="ADR.Date" type="text" value="6/07/2023" data-role="datepicker" role="combobox" aria-expanded="false" aria-haspopup="grid" aria-controls="ADR_Date_dateview" autocomplete="off" aria-disabled="false" aria-readonly="false" aria-describedby="ADR_Date-error" aria-invalid="false">
  <button aria-label="select" tabindex="-1" class="k-input-button k-button k-icon-button k-button-md k-button-solid k-button-solid-base" type="button" role="button">
    <span class="k-icon k-i-calendar k-button-icon"></span>
  </button>
</span>

额外说明

Kendo的TagHelper不会直接渲染HTML结构,而是生成jQuery初始化脚本:

<script>kendo.syncReady(function(){jQuery("#ADR_Date").kendoDatePicker({"format":"d","value":new Date(2023,6,6,0,0,0,0)});});</script>

解决方案

Kendo DatePicker的TagHelper本质是生成前端初始化配置,而非直接输出HTML,所以无法通过服务端直接修改它的子元素。你需要通过Kendo自身的配置参数来传递样式类:

方案1:视图层直接动态配置

在使用kendo-datepicker的视图中,通过html-attributes结合ModelState动态添加错误类:

<kendo-datepicker for="ADR.Date" 
                  html-attributes='new { @class = ViewData.ModelState.IsValidField("ADR.Date") ? "form-control" : "form-control is-invalid" }'>
</kendo-datepicker>

方案2:改进TagHelper配置传递

修改TagHelper,通过更新Kendo的html-attributes属性,让Kendo在生成input时自动带上错误类:

[HtmlTargetElement("kendo-datepicker")]
public class ValidationErrorClassTagHelper : TagHelper
{
    [HtmlAttributeNotBound]
    [ViewContext]
    public ViewContext ViewContext { get; set; }

    // 绑定Kendo DatePicker的html-attributes属性
    [HtmlAttributeName("html-attributes")]
    public IDictionary<string, object> HtmlAttributes { get; set; } = new Dictionary<string, object>();

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        var forAttr = context.AllAttributes["for"];
        if (forAttr == null) return;

        var modelExpression = (ModelExpression)forAttr.Value;
        if (ViewContext.ViewData.ModelState.TryGetValue(modelExpression.Name, out var entry) 
            && entry.Errors.Any())
        {
            // 合并已有类和错误类
            if (HtmlAttributes.TryGetValue("class", out var existingClass))
            {
                HtmlAttributes["class"] = $"{existingClass} is-invalid";
            }
            else
            {
                HtmlAttributes["class"] = "form-control is-invalid";
            }

            // 更新输出的html-attributes属性
            output.Attributes.SetAttribute("html-attributes", HtmlAttributes);
        }
    }
}

原理说明

Kendo的TagHelper会将html-attributes中的配置传递给前端初始化代码,最终生成的input元素会带上这些样式类。之前的错误在于直接修改了外层容器span的类,而我们需要的是给内部input配置样式,必须通过Kendo的参数传递才能生效。


内容的提问来源于stack exchange,提问作者Reafidy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 12:41:38