Razor 用于验证消息的自定义HTML帮助程序
我为验证消息的输出编写了一个定制的HTTML助手标记。它工作正常,但它始终存在Razor 用于验证消息的自定义HTML帮助程序,razor,asp.net-core,Razor,Asp.net Core,我为验证消息的输出编写了一个定制的HTTML助手标记。它工作正常,但它始终存在 @Html.MyValidationMsg(m=>m.FirstName) public static IHtmlContent MyValidationMsg(此IHTML帮助器,表达式) { MemberExpression MemberExpression=expression.Body作为MemberExpression; var reqAttrib=memberExpression.Member .GetC
@Html.MyValidationMsg(m=>m.FirstName)
public static IHtmlContent MyValidationMsg(此IHTML帮助器,表达式)
{
MemberExpression MemberExpression=expression.Body作为MemberExpression;
var reqAttrib=memberExpression.Member
.GetCustomAttributes(typeof(RequiredAttribute),false)
.Cast()
.SingleOrDefault();
var displayAttrib=memberExpression.Member
.GetCustomAttributes(typeof(DisplayAttribute),false)
.Cast()
.SingleOrDefault();
var errMsg=reqAttrib.ErrorMessage??displayAttrib.Name+“是必需的。”;
var content=new-HtmlContentBuilder()
.AppendHtml(“”)
.AppendHtml(“”)
.AppendHtml(“”)
.AppendHtml(“”)
.AppendHtml(“”)
.AppendHtml(“”)
.AppendHtml(“”)
.AppendHtml(“”)
.AppendHtml(“”)
.AppendHtml(“”)
.AppendHtml(errMsg)
.AppendHtml(“”)
.附录HTML(“”);
返回内容;
}
如何在Razor页面的初始加载时隐藏它,以及在字段无效时使其显示
感谢您的帮助有两个原因导致该消息总是出现
var errMsg=reqAttrib.erromessage??displayAttrib.Name+“是必需的。”
使其返回一些值,即使根本没有记录[required]
属性
但不要将其更改为var errMsg=reqAttrib.ErrorMessage!=无效的displayAttrib.Name+“是必需的。”
,因为reqAttrib
可能是null
。相反,您可以按以下方式更改代码:
var errMsg = reqAttrib==null ?
"":
reqAttrib?.ErrorMessage ?? displayName + " is required.";
public static IHtmlContent MyValidationMsg<TModel, TProperty>(this IHtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
{
MemberExpression memberExpression = expression.Body as MemberExpression;
var reqAttrib = memberExpression.Member
.GetCustomAttributes(typeof(RequiredAttribute), false)
.Cast<RequiredAttribute>()
.SingleOrDefault();
var contentBuilder = new HtmlContentBuilder();
// if the current property has no [Required] attribute, there's no need to display required message
if(reqAttrib == null ){return contentBuilder; }
// check the value of current property
var compiled = expression.Compile();
var model = (TModel) helper.ViewData.Model ;
if(model == null){
throw new Exception("No Model associated with the view !");
}
var propValue = (TProperty) compiled.Invoke(model);
// I just test nullable props here, you might custom it to fulfill your requirements, eg : whether the length of string matches
if(propValue != null){ return contentBuilder; }
var member = memberExpression.Member;
var displayName= member
.GetCustomAttributes(typeof(DisplayAttribute), false)
.Cast<DisplayAttribute>()
.SingleOrDefault()
?.Name // might be null
?? member.Name; // fall back
var errMsg = reqAttrib==null ?
"":
reqAttrib?.ErrorMessage ?? displayName + " is required.";
if(String.IsNullOrEmpty(errMsg)){ return contentBuilder; }
return contentBuilder
.AppendHtml("<div class=\"rvt-inline-alert rvt-inline-alert--standalone rvt-inline-alert--danger\">")
.AppendHtml("<span class=\"rvt-inline-alert__icon\">")
.AppendHtml("<svg aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\">")
.AppendHtml("<g fill=\"currentColor\">")
.AppendHtml("<path d=\"M8,0a8,8,0,1,0,8,8A8,8,0,0,0,8,0ZM8,14a6,6,0,1,1,6-6A6,6,0,0,1,8,14Z\" />")
.AppendHtml("<path d=\"M10.83,5.17a1,1,0,0,0-1.41,0L8,6.59,6.59,5.17A1,1,0,0,0,5.17,6.59L6.59,8,5.17,9.41a1,1,0,1,0,1.41,1.41L8,9.41l1.41,1.41a1,1,0,0,0,1.41-1.41L9.41,8l1.41-1.41A1,1,0,0,0,10.83,5.17Z\"/>")
.AppendHtml("</g>")
.AppendHtml("</svg>")
.AppendHtml("</span>")
.AppendHtml("<span class=\"rvt-inline-alert__message\" role=\"alert\" id=\"radio-list-message\">")
.AppendHtml(errMsg)
.AppendHtml("</span>")
.AppendHtml("</div>");
}
[Required]
属性,并且它确实分配了一个值,那么我们不应该显示所需的消息,如“xxx需要”null对象引用的bug
:
var displayAttrib = memberExpression.Member
.GetCustomAttributes(typeof(DisplayAttribute), false)
.Cast<DisplayAttribute>()
.SingleOrDefault();
var errMsg = reqAttrib.ErrorMessage ?? displayAttrib.Name + " is required.";
非常感谢@itminus花时间让我走上了正确的道路 我最终完全是为了重写jquery.validate而划出了这条路径。还使用javascript/jquery操纵DOM以获得所需的结果 错误消息的所需输出:
<div class="rvt-inline-alert rvt-inline-alert--danger">
<span class="rvt-inline-alert__icon">
<svg width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">
<g fill="currentColor">
<path d="M8,0a8,8,0,1,0,8,8A8,8,0,0,0,8,0ZM8,14a6,6,0,1,1,6-6A6,6,0,0,1,8,14Z"/>
<path d="M10.83,5.17a1,1,0,0,0-1.41,0L8,6.59,6.59,5.17A1,1,0,0,0,5.17,6.59L6.59,8,5.17,9.41a1,1,0,1,0,1.41,1.41L8,9.41l1.41,1.41a1,1,0,0,0,1.41-1.41L9.41,8l1.41-1.41A1,1,0,0,0,10.83,5.17Z"/>
</g>
</svg>
</span>
<span class="rvt-inline-alert__message" role="alert">Your Name is required.</span>
</div>
我猜var errMsg=reqAttrib.ErrorMessage??displayAttrib.Name+“是必需的。”;这将始终返回一些值。尝试下面的var errMsg=reqAttrib.ErrorMessage!=无效的displayAttrib.Name+“是必需的。”:“”;然后用JavaScript返回内容,如果ErrMSG.List.0是答案,但是尝试在进行这条路径之前考虑FuffTrimeValue:你用我的代码来窃取bug,“ITMIUS?!?!!!!!!!!!!你一定是疯了!!:)我不太了解表达式和compile()的情况。我需要更多的了解。然而,我并没有试图改变字段的验证方式。
[Required]
的默认例程对我来说很好。我只是想定制从
生成的HTML输出——有更好的方法吗?一如既往——谢谢@Fraze我以为你在使用@(Html.MyValidationMsg(m=>lambda\u来获取你的属性))的MyValidationMsg()
。因此,如果属性A已经有一个值,则无需显示“A是必需的”。@Fraze这里的编译和调用用于调用表达式,以便我们可以获得属性的实际值。您是正确的。我使用的是这样的:@Html.MyValidationMsg(m=>User.Name)
。这里我唯一的目标是将validator助手的HTML输出更改为代码中MyValidationMsg的输出。如果有更好的方法来控制HTML输出,那么也许我只是做错了?@Fraze可能做得不错!awesome$.validator.unobtrusive.options=设置代码>
<div class="rvt-inline-alert rvt-inline-alert--danger">
<span class="rvt-inline-alert__icon">
<svg width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">
<g fill="currentColor">
<path d="M8,0a8,8,0,1,0,8,8A8,8,0,0,0,8,0ZM8,14a6,6,0,1,1,6-6A6,6,0,0,1,8,14Z"/>
<path d="M10.83,5.17a1,1,0,0,0-1.41,0L8,6.59,6.59,5.17A1,1,0,0,0,5.17,6.59L6.59,8,5.17,9.41a1,1,0,1,0,1.41,1.41L8,9.41l1.41,1.41a1,1,0,0,0,1.41-1.41L9.41,8l1.41-1.41A1,1,0,0,0,10.83,5.17Z"/>
</g>
</svg>
</span>
<span class="rvt-inline-alert__message" role="alert">Your Name is required.</span>
</div>
<script type="text/javascript">
var settings = {
errorElement: "span",
errorClass: "rvt-validation-danger", //around textbox on error
errorPlacement: function (error, element) {
var avg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
avg.setAttribute("width", "16");
avg.setAttribute("height", "16");
avg.setAttribute("viewBox", "0 0 16 16");
avg.setAttribute("aria-hidden", "true");
var g = document.createElement("g");
g.setAttribute("fill", "currentColor");
var p1 = document.createElement("path");
p1.setAttribute("d", "M8,0a8,8,0,1,0,8,8A8,8,0,0,0,8,0ZM8,14a6,6,0,1,1,6-6A6,6,0,0,1,8,14Z");
var p2 = document.createElement("path");
p2.setAttribute("d", "M10.83,5.17a1,1,0,0,0-1.41,0L8,6.59,6.59,5.17A1,1,0,0,0,5.17,6.59L6.59,8,5.17,9.41a1,1,0,1,0,1.41,1.41L8,9.41l1.41,1.41a1,1,0,0,0,1.41-1.41L9.41,8l1.41-1.41A1,1,0,0,0,10.83,5.17Z");
g.appendChild(p1);
g.appendChild(p2);
avg.appendChild(g);
var spanIcon = document.createElement("span");
spanIcon.setAttribute("class", "rvt-inline-alert__icon");
spanIcon.innerHTML += avg.outerHTML;
var spanMsg = document.createElement("span");
spanMsg.setAttribute("class", "rvt-inline-alert__message");
spanMsg.setAttribute("role", "alert");
spanMsg.innerHTML += error[0].innerHTML;
var c = document.createElement("div");
c.setAttribute("class", "rvt-inline-alert rvt-inline-alert--danger");
c.innerHTML += spanIcon.outerHTML + spanMsg.outerHTML;
error.replaceWith(c);
}
};
$.validator.unobtrusive.options = settings;
</script>