对于验证摘要,您通常会遇到以下情况:
<div asp-validation-summary="ModelOnly" class="..."></div>
,如果有一个空字符串的错误,因为字段/属性将显示在<ul>
列表中的该div内。
如果我想使用具有特定div
属性的class
s序列来显示它们,该怎么办?或任何其他自定义格式?
对于字段验证,您通常会这样做:
<div class="form-group">
<label asp-for="OldPassword"></label>
<input asp-for="OldPassword" class="form-control" />
<span asp-validation-for="OldPassword" class="text-danger"></span>
</div>
并将错误作为文本插入span
元素中。
我正在使用一个模板,该模板需要将has-errors
类应用于form-group
div
元素,以防出现错误,因为它需要设置标签和输入的样式。
它还要求span
为div
(由于某些未知原因),令人惊讶的是,将span
更改为div
会阻止div插入文本错误;更不用说将span
包裹在div
内会产生div
应用了适当间距的问题,所以即使没有错误,div也显示出令人讨厌的空间。
处理自定义表单验证格式(尝试干,因为我的应用程序有很多表单)以及上面显示的自定义规则最常用的方法是什么?
答案 0 :(得分:8)
以下是一些扩展点,您可以考虑为验证摘要和字段验证错误提供自定义呈现:
IHtmlGenerator
)Tag Helpers
) asp-validation-summary
和asp-validation-for
代码帮助程序使用GenerateValidationSummary
服务的注册实现的GenerateValidationMessage
和IHtmlGenerator
方法,默认情况下为DefaultHtmlGenerator
。
您可以提供导出DefaultHtmlGenerator
的自定义实现并覆盖这些方法,然后在启动时注册该服务。这样,这些标记帮助程序将使用您的自定义实现。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddTransient<IHtmlGenerator, MyHtmlGenerator>();
}
以下是source code of DefaultHtmlGenerator
的链接,可帮助您自定义实施。
示例 - 创建新的实现IHtmlGenerator
这是一个简单的示例,用于显示所需的命名空间和方法,以及可以进入自定义实现的内容。在您提供自定义实施后,请不要忘记在ConfigureServices
中注册,就像我上面所做的那样。
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.Extensions.Options;
using System.Text.Encodings.Web;
namespace ValidationSampleWebApplication
{
public class MyHtmlGenerator : DefaultHtmlGenerator
{
public MyHtmlGenerator(IAntiforgery antiforgery, IOptions<MvcViewOptions> optionsAccessor, IModelMetadataProvider metadataProvider, IUrlHelperFactory urlHelperFactory, HtmlEncoder htmlEncoder, ValidationHtmlAttributeProvider validationAttributeProvider)
: base(antiforgery, optionsAccessor, metadataProvider, urlHelperFactory, htmlEncoder, validationAttributeProvider)
{
}
public override TagBuilder GenerateValidationMessage(ViewContext viewContext, ModelExplorer modelExplorer, string expression, string message, string tag, object htmlAttributes)
{
return base.GenerateValidationMessage(viewContext, modelExplorer, expression, message, tag, htmlAttributes);
}
public override TagBuilder GenerateValidationSummary(ViewContext viewContext, bool excludePropertyErrors, string message, string headerTag, object htmlAttributes)
{
return base.GenerateValidationSummary(viewContext, excludePropertyErrors, message, headerTag, htmlAttributes);
}
}
}
你也可以author your custom tag helpers。为此,它足以从TagHelper
派生并覆盖Process
方法。
然后,您只需在视图中注册已创建的标记助手,或在_ViewImports.cshtml
:
@using ValidationSampleWebApplication
@using ValidationSampleWebApplication.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, ValidationSampleWebApplication
同样,在创建自定义标记帮助程序以进行验证时,您可以考虑:
示例 - 将hasError类添加到表单组div
在此示例中,我创建了一个asp-myvalidation-for
,可以div
这样的方式应用<div class="form-group" asp-myvalidation-for="LastName">
元素,并将hasError
类添加到{{1}如果指定的字段有验证错误。不要忘记在div
注册它,就像我上面所做的那样。
_ViewImports.cshtml
示例 - 将using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.AspNetCore.Mvc.TagHelpers;
using Microsoft.AspNetCore.Mvc.ModelBinding;
namespace ValidationSampleWebApplication
{
[HtmlTargetElement("div", Attributes = MyValidationForAttributeName)]
public class MyValidationTagHelper : TagHelper
{
private const string MyValidationForAttributeName = "asp-myvalidation-for";
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
[HtmlAttributeName(MyValidationForAttributeName)]
public ModelExpression For { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
base.Process(context, output);
ModelStateEntry entry;
ViewContext.ViewData.ModelState.TryGetValue(For.Name, out entry);
if (entry != null && entry.Errors.Count > 0)
{
var builder = new TagBuilder("div");
builder.AddCssClass("hasError");
output.MergeAttributes(builder);
}
}
}
}
类添加到表单组div
在以下示例中,我已向标准field-validation-error
代码帮助程序添加了div
支持。现有的标记助手只支持div元素。在此,我已向asp-validation-for
代码帮助程序添加了div
支持,如果出现错误,则会添加asp-validation-for
,否则,field-validation-error
将会{ {1}}课程。
标签的默认行为是,如果标签包含内容,它不会对标签内容进行任何更改。因此,将标记帮助器添加到空div
将向span添加验证错误,但对于具有某些内容的div,它只是更改div的类。不要忘记在field-validation-valid
注册它,就像我上面所做的那样。
span
答案 1 :(得分:0)
使用自定义标记助手我提出了以下解决方案:
[HtmlTargetElement("ul", Attributes = AttributeName)]
public class ValidationSummaryLiItemsTagHelper : TagHelper
{
private const string AttributeName = "model-validation-summary-list";
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
var errors = ViewContext.ModelState.Where(x => x.Key == "").SelectMany(x => x.Value.Errors).ToList();
foreach (var error in errors)
{
output.Content.AppendFormat("<li>{0}</li>", error.ErrorMessage);
}
if (errors.Any() == false)
output.SuppressOutput();
}
}
后来我可以这样使用它:
<ul class="some-css-class" id="some-id-name" model-validation-summary-list></ul>
然后,例如,我可以使用bootstrap类直接自定义ul
容器或添加任何html属性。