EditorFor Tag Helper使用FluentValidator时不呈现验证属性

问题描述 投票:6回答:1

我有一个像这样的简单形式,它使用@ Html.EditorFor扩展名:

<form method="post">
    @Html.EditorFor(x => x.SystemSettings.EmailFromAddress)
    <submit-button title="Save"></submit-button>
</form>

我想利用.NET Core的标记帮助器,使我的表单看起来像这样:

<form method="post">
    <editor asp-for="SystemSettings.EmailFromAddress"/>
    <submit-button title="Save"></submit-button>
</form>

我最终也希望拥有自己的自定义标签帮助程序,因此我可以执行以下操作:

<text-box asp-for="SystemSettings.EmailFromAddress"></text-box>

我有一个string模板,该模板由@ Html.EditorFor扩展名呈现:

@model string
<div class="form-group">
    <label asp-for="@Model" class="m-b-none"></label>
    <span asp-description-for="@Model" class="help-block m-b-none small m-t-none"></span>
    <div class="input-group">
        <input asp-for="@Model" class="form-control" />
        <partial name="_ValidationIcon" />
    </div>
    <span asp-validation-for="@Model" class="validation-message"></span>
</div>

为此,我看到有人实现了一个EditorTagHelper,看起来像这样:

[HtmlTargetElement("editor", TagStructure = TagStructure.WithoutEndTag,
    Attributes = ForAttributeName)]
public class EditorTagHelper : TagHelper
{
    private readonly IHtmlHelper _htmlHelper;

    private const string ForAttributeName = "asp-for";
    private const string TemplateAttributeName = "asp-template";

    [HtmlAttributeName(ForAttributeName)]
    public ModelExpression For { get; set; }


    [HtmlAttributeName(TemplateAttributeName)]
    public string Template { get; set; }

    [ViewContext]
    [HtmlAttributeNotBound]
    public ViewContext ViewContext { get; set; }

    public EditorTagHelper(IHtmlHelper htmlHelper)
    {
        _htmlHelper = htmlHelper;
    }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        if (context == null)
            throw new ArgumentNullException(nameof(context));

        if (output == null)
            throw new ArgumentNullException(nameof(output));

        if (!output.Attributes.ContainsName(nameof(Template)))
        {
            output.Attributes.Add(nameof(Template), Template);
        }

        output.SuppressOutput();

        (_htmlHelper as IViewContextAware).Contextualize(ViewContext);

        output.Content.SetHtmlContent(_htmlHelper.Editor(For.Name, Template));

        await Task.CompletedTask;
    }
}

但是当我使用EditorTagHelper时,似乎缺少了不显眼的Javascript验证属性:

使用@ Html.EditorFor,将呈现此内容:

<input class="form-control valid" type="text" data-val="true" data-val-required="Email From Address cannot be empty" id="SystemSettings_EmailFromAddress" name="SystemSettings.EmailFromAddress" value="[email protected]" aria-required="true" aria-invalid="false" aria-describedby="SystemSettings_EmailFromAddress-error">

它具有data-val属性,因此可以应用客户端验证。

当我改用EditorTagHelper时,将显示:

<input class="form-control valid" type="text" id="SystemSettings_EmailFromAddress" name="SystemSettings.EmailFromAddress" value="[email protected]" aria-invalid="false">

不被采用的验证属性。我正在使用FluentValidation,并且已经指定了AbstractValidator:

public class SystemSettingsValidator : AbstractValidator<SystemSettings>
{
    public SystemSettingsValidator()
    {
        RuleFor(x => x.EmailFromAddress).NotEmpty()
            .WithMessage("Email From Address cannot be empty");
    }
}

[我发现,如果删除了AbstractorValidator并仅向模型属性添加了[Required]属性,则验证可以正常进行。这表明FluentValidation出了点问题。也许存在配置问题。

我正在使用Autofac依赖项注入来扫描我的程序集并注册验证器类型:

builder.RegisterAssemblyTypes(Assembly.Load(assembly))
    .Where(t => t.IsClosedTypeOf(typeof(IValidator<>)))
    .AsImplementedInterfaces()
    .PropertiesAutowired()
    .InstancePerLifetimeScope();

这似乎很好。以防万一,我还尝试从流利的验证选项中注册验证器,如下所示:

.AddFluentValidation(fv =>
{
    fv.RegisterValidatorsFromAssemblies(new List<Assembly>
        {Assembly.GetExecutingAssembly(), Assembly.Load(nameof(Entities))});
})

这似乎也很好。

要注意的一件事是,我以前遇到的一个问题是,当包含标签助手时,使用Autofac程序集扫描会破坏应用程序。我添加了一个过滤器以确保注册这些依赖项时不包括标签助手,例如

builder.RegisterAutowiredAssemblyInterfaces(Assembly.Load(Web))
    .Where(x => !x.Name.EndsWith("TagHelper"));

我已经在此处上传了代码的工作示例:https://github.com/ciaran036/coresample2

导航到Settings Page以查看我要验证的字段。

此问题似乎也影响视图组件。

谢谢。

asp.net-core autofac fluentvalidation tag-helpers
1个回答
0
投票

我相信问题出在标签帮助程序中,因为它使用IHtmlHelper.Editor而不是IHtmlHelper<TModel>.EditorFor来生成HTML内容。它们并不完全相同。

© www.soinside.com 2019 - 2024. All rights reserved.