提问人:Reafidy 提问时间:8/14/2023 最后编辑:Reafidy 更新时间:9/19/2023 访问量:130
自定义验证 TagHelper:修改子元素
Custom Validation TagHelper: Modify Child Element
问:
我正在尝试通过更改 TagHelper 中 HTML 子元素的类来实现服务器端验证。TagHelper 是“kendo-datepicker”,但是当前代码修改了“span”标签的类,我想修改子“input”标签的类。
经过一番研究,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)
{
//output.Attributes.ContainsName("class")
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>
不幸的是,taghelperoutput 正在渲染 jquery 而不是 html:
PostElement = <script>kendo.syncReady(function(){jQuery("#ADR_Date").kendoDatePicker({"format":"d","value":new Date(2023,6,6,0,0,0,0)});});</script>
答:
一个非常原始的想法是做
TagHelperContent innerContent = await output.GetChildContentAsync();
然后通过 As a 获取内容,然后解析它,然后在添加 .这是一个公认的肮脏的解决方案,只有在我们无能为力的情况下,我们才应该求助于。GetContent
string
string
SetContent
class
或者,您可以查看输入是否在某个键下。如果是这样,那么您可以使用那个。context.Items
我认为最简单的方法是:
if (entry != null && entry.Errors.Any()) {
// Asynchronously get string containing child content
string childContent = (await output.GetChildContentAsync()).GetContent();
// Insert your classes by matching the opening input tag along with the class attribute and replacing it.
string modifiedContent = Regex.Replace(
childContent,
Regex.Escape("<input class=\""),
"<input class=\"form-control is-invalid ");
// Update the output
output.Content.SetHtmlContent(modifiedContent);
}
注意:如果您的 HTML 结构发生更改以包含第二个输入,则需要更新。
字符串操作并不是执行此操作的首选方法,但如果没有有关问题的其他上下文,这是最直接的方法。根据您的环境,可能会导致问题。如果是这种情况,请删除正则表达式中的前导,并更新为 .我只是为了跳过对 的调用而将它包含在内,以提高极小的性能。SetHtmlContent()
<
SetHtmlContent()
SetContent()
HTMLEncoder.Encode()
评论
PostElement = <script>kendo.syncReady(function(){jQuery("#ADR_Date").kendoDatePicker({"format":"d","value":new Date(2023,6,6,0,0,0,0)});});</script>
您可以使用 GetChildContentAsync() 修改“kendo-datepicker”标记助手中的“input”子元素,如下所示:
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())
{
var childContent = await output.GetChildContentAsync();
var inputElement = childContent.FindDescendants("input").FirstOrDefault();
if (inputElement != null)
{
inputElement.Attributes.Add("class", "form-control is-invalid");
}
}
}
}
在此代码中,childContent.FindDescendants(“input”) 方法用于查找和检索 childContent 中与给定标记名称“input”匹配的所有后代元素 FirstOrDefault() 是用于从 返回的匹配元素集合中获取第一个元素的方法。FindDescendants(“输入”)。
试一试,让我们知道您是否设法正确解决了您的案件。
评论