英文:
ASP.NET Razor Pages check property validation state?
问题
我正在尝试使用ASP.NET 7.0中的Razor页面编写网站,并尝试使用Bootstrap 5.1表单在客户端上显示服务器端验证消息。
Bootstrap提供了invalid-feedback
和valid-feedback
类,这些类会在输入字段经过验证后(在不成功的POST请求之后)应用于输入字段。然而,要有条件地显示这些消息,输入字段必须分别标记为is-invalid
或is-valid
。我如何获取这些信息?
我知道我可以使用HTML助手从HTML助手或IHtmlHelper
中获取验证消息:
<label asp-for="Name" class="form-label"></label>
<input asp-for="Name" class="form-select @(IsValid ? "is-valid" : "is-invalid")" />
<div class="invalid-feedback">
<!-- <span>@Html.ValidationMessageFor(i => i.Name)</span> -->
<span asp-validation-for="Name"></span>
</div>
我想创建类似第二行的东西,其中我将类应用于输入。然而,当所有这些逻辑位于另一个EditorTemplate内部时,我无法从模型中获取ValidationState。到目前为止,我尝试使用与ValidationMessageFor用于检查该字典的方法相同的方法来获取属性在ModelStateDictionary中使用的键,但它们在该类中不是公开可用的,我还尝试在HtmlHelper中查找可以让我访问该验证状态的方法。
到目前为止,我尝试在Html助手上使用扩展方法,但没有不知道确切键的情况下没有ValidationState方法,这在嵌套属性中是困难的:
Html.ViewContext.ModelState.GetValidationState(key)
英文:
I am trying to write a website using Razor pages in ASP.NET 7.0 and I am trying to get server side validation messages to display on the client using bootstrap 5.1 forms.
Bootstrap provides the class invalid-feedback
and valid-feedback
which are applied to the input field once the field is validated (after an unsuccessful post request). However to display the messages conditionally the input fields must be tagged with is-invalid
or is-valid
respectively. How do I get this information?
I know that I can get the validation message from the html helper using either the ValidationMessageTagHelper
or the IHtmlHelper
:
<label asp-for="Name" class="form-label"></label>
<input asp-for="Name" class="form-select @(IsValid ? "is-valid" : "is-invalid")" />
<div class="invalid-feedback">
<!-- <span>@Html.ValidationMessageFor(i => i.Name)</span> -->
<span asp-validation-for="Name"></span>
</div>
I want to make something similar to the second line where I apply the class to the input. However I cannot get the ValidationState from the Model, especially when all this logic is inside another EditorTemplate. So far I tried to get the Key that the property uses in the ModelStateDictionary using the same methods that ValidationMessageFor use to check that dictionary, but they are not publicly available in that class and I also tried to find methods in the HtmlHelper that give me access to that validation state.
So far I tried to use an extension method on the Html helper, but there is no ValidationState method without knowing the exact key, which is difficult in nested properties:
Html.ViewContext.ModelState.GetValidationState(key)
答案1
得分: 2
根据我的评论,我发现NameFor
函数可以实现我要的功能:
public static class HtmlExtensions {
/// <inheritdoc cref="ModelStateDictionary.GetValidationState(string)"/>
/// <param name="property">提供键的属性。</param>
public static ModelValidationState GetValidationState<TModel, TPropertyType>(this IHtmlHelper<TModel> helper, Expression<Func<TModel, TPropertyType>> property)
=> helper.ViewContext.ModelState.GetValidationState(helper.NameFor(property));
public static string GetValidityClass<TModel, TPropertyType>(this IHtmlHelper<TModel> helper, Expression<Func<TModel, TPropertyType>> property)
=> helper.GetValidationState(property) switch {
ModelValidationState.Invalid => "is-invalid",
ModelValidationState.Valid => "is-valid",
_ => string.Empty,
};
}
现在我可以使用这个扩展来应用类似这样的类:
<div class="col-md-6">
<label asp-for="Name" class="form-label"></label>
<input asp-for="Name" class="form-control @Html.GetValidityClass(i => i.Name)" />
<div class="invalid-feedback"><span asp-validation-for="Name"></span></div>
</div>
英文:
As in my comment I figured the NameFor
function does what I am looking for:
public static class HtmlExtensions {
/// <inheritdoc cref="ModelStateDictionary.GetValidationState(string)"/>
/// <param name="property">Property that provides the key.</param>
public static ModelValidationState GetValidationState<TModel, TPropertyType>(this IHtmlHelper<TModel> helper, Expression<Func<TModel, TPropertyType>> property)
=> helper.ViewContext.ModelState.GetValidationState(helper.NameFor(property));
public static string GetValidityClass<TModel, TPropertyType>(this IHtmlHelper<TModel> helper, Expression<Func<TModel, TPropertyType>> property)
=> helper.GetValidationState(property) switch {
ModelValidationState.Invalid => "is-invalid",
ModelValidationState.Valid => "is-valid",
_ => string.Empty,
};
}
Now I can use this extension to apply the class like this:
<div class="col-md-6">
<label asp-for="Name" class="form-label"></label>
<input asp-for="Name" class="form-control @Html.GetValidityClass(i => i.Name)" />
<div class="invalid-feedback"><span asp-validation-for="Name"></span></div>
</div>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论