gpt4 book ai didi

asp.net-mvc-3 - ASP.NET MVC3 自定义验证消息行为

转载 作者:行者123 更新时间:2023-12-04 06:00:29 24 4
gpt4 key购买 nike

来自 asp.net webforms 模型,我习惯于使用在表单中显示错误的验证器 <span title="Username is Required">*</span> .

我很清楚 MVC3 验证器是如何开箱即用的,所以请不要再解释验证器在 MVC3 中的工作原理,因为我很确定我已经做到了。我想要完成的是将验证错误消息显示为跨度标记的标题,如第一段所示。

我已经设法在 MVC3 中复制了这一点,但不确定我的做法是否遵循最佳实践。对于是否有更好的方法来完成同样的事情,我将不胜感激。如果不用修改 jquery.validate.unobtrusive.js 就可以完成,那就太好了。

所以我所做的是:

  • 将验证消息设置为“*”
  • 在其有效时隐藏验证消息
  • 添加了一个新属性来确定是否将消息添加为标题
  • 在 onError 中添加了 2 行标记代码以检查是否在标题中显示错误消息,如果显示则显示。
  •     [.cshtml]    @Html.ValidationMessageFor(m => m.Email, "*", new { data_val_usetitle = "true" })

    [.css] .field-validation-valid {display:none;}

    .js] function onError(error, inputElement) { // 'this' is the form element
    var container = $(this).find("[data-valmsg-for='" + inputElement[0].name + "']"),
    replace = $.parseJSON(container.attr("data-valmsg-replace")) !== false,
    useTitle = $.parseJSON(container.attr("data-val-usetitle")) !== false; /* New Line */

    container.removeClass("field-validation-valid").addClass("field-validation-error");
    error.data("unobtrusiveContainer", container);

    if (replace) {
    container.empty();
    error.removeClass("input-validation-error").appendTo(container);
    }
    else {
    if (useTitle) container.attr("title", error.text()); /* New Line */
    error.hide();
    }
    }

    最佳答案

    我认为你所做的是最干净的方式。没有办法修改 jquery.validate.unobtrusive.js 因为 MVC 扩展不遵循老派的 asp.net 方法来即时发出 javascript。

    我刚刚创建了我自己的名为 ValidationIconFor() 的自定义验证扩展,以便显示单个图像,其标题设置为错误消息,并且我使用了上面代码的修改版本。

    jquery.validate.unobtrusive.js :

    function onError(error, inputElement) {  // 'this' is the form element
    var container = $(this).find("[data-valmsg-for='" + inputElement[0].name + "']"),
    replace = $.parseJSON(container.attr("data-valmsg-replace")) !== false,
    useTitle = $.parseJSON(container.attr("data-val-usetitle")) !== false;

    container.removeClass("field-validation-valid").addClass("field-validation-error");
    error.data("unobtrusiveContainer", container);

    if (replace) {
    container.empty();
    if (useTitle)
    container.attr("title", error.text());
    else
    error.removeClass("input-validation-error").appendTo(container);
    }
    else {
    if (useTitle)
    container.attr("title", error.text());
    error.hide();
    }
    }

    ValidationExtensions.cs :
    public static class ValidationExtensions
    {
    private static string _resourceClassKey;

    public static string ResourceClassKey
    {
    get
    {
    return _resourceClassKey ?? String.Empty;
    }
    set
    {
    _resourceClassKey = value;
    }
    }

    private static FieldValidationMetadata ApplyFieldValidationMetadata(HtmlHelper htmlHelper, ModelMetadata modelMetadata, string modelName)
    {
    FormContext formContext = htmlHelper.ViewContext.FormContext;
    FieldValidationMetadata fieldMetadata = formContext.GetValidationMetadataForField(modelName, true /* createIfNotFound */);

    // write rules to context object
    IEnumerable<ModelValidator> validators = ModelValidatorProviders.Providers.GetValidators(modelMetadata, htmlHelper.ViewContext);
    foreach (ModelClientValidationRule rule in validators.SelectMany(v => v.GetClientValidationRules()))
    {
    fieldMetadata.ValidationRules.Add(rule);
    }

    return fieldMetadata;
    }

    private static string GetInvalidPropertyValueResource(HttpContextBase httpContext)
    {
    string resourceValue = null;
    if (!String.IsNullOrEmpty(ResourceClassKey) && (httpContext != null))
    {
    // If the user specified a ResourceClassKey try to load the resource they specified.
    // If the class key is invalid, an exception will be thrown.
    // If the class key is valid but the resource is not found, it returns null, in which
    // case it will fall back to the MVC default error message.
    resourceValue = httpContext.GetGlobalResourceObject(ResourceClassKey, "InvalidPropertyValue", CultureInfo.CurrentUICulture) as string;
    }
    return resourceValue ?? "The value '{0}' is invalid.";
    }

    private static string GetUserErrorMessageOrDefault(HttpContextBase httpContext, ModelError error, ModelState modelState)
    {
    if (!String.IsNullOrEmpty(error.ErrorMessage))
    {
    return error.ErrorMessage;
    }
    if (modelState == null)
    {
    return null;
    }

    string attemptedValue = (modelState.Value != null) ? modelState.Value.AttemptedValue : null;
    return String.Format(CultureInfo.CurrentCulture, GetInvalidPropertyValueResource(httpContext), attemptedValue);
    }

    [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
    public static MvcHtmlString ValidationIconFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
    return ValidationIconFor(htmlHelper, expression, null /* validationMessage */, new RouteValueDictionary());
    }

    [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
    public static MvcHtmlString ValidationIconFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string validationMessage)
    {
    return ValidationIconFor(htmlHelper, expression, validationMessage, new RouteValueDictionary());
    }

    [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
    public static MvcHtmlString ValidationIconFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string validationMessage, object htmlAttributes)
    {
    return ValidationIconFor(htmlHelper, expression, validationMessage, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    }

    [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
    public static MvcHtmlString ValidationIconFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string validationMessage, IDictionary<string, object> htmlAttributes)
    {
    return ValidationMessageHelper(htmlHelper,
    ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
    ExpressionHelper.GetExpressionText(expression),
    validationMessage,
    htmlAttributes);
    }

    [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "Normalization to lowercase is a common requirement for JavaScript and HTML values")]
    private static MvcHtmlString ValidationMessageHelper(this HtmlHelper htmlHelper, ModelMetadata modelMetadata, string expression, string validationMessage, IDictionary<string, object> htmlAttributes)
    {
    string modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
    FormContext formContext = htmlHelper.ViewContext.FormContext;

    if (!htmlHelper.ViewData.ModelState.ContainsKey(modelName) && formContext == null)
    {
    return null;
    }

    ModelState modelState = htmlHelper.ViewData.ModelState[modelName];
    ModelErrorCollection modelErrors = (modelState == null) ? null : modelState.Errors;
    ModelError modelError = (((modelErrors == null) || (modelErrors.Count == 0)) ? null : modelErrors.FirstOrDefault(m => !String.IsNullOrEmpty(m.ErrorMessage)) ?? modelErrors[0]);

    if (modelError == null && formContext == null)
    {
    return null;
    }

    TagBuilder builder = new TagBuilder("img");
    builder.MergeAttributes(htmlAttributes);
    builder.AddCssClass((modelError != null) ? HtmlHelper.ValidationMessageCssClassName : HtmlHelper.ValidationMessageValidCssClassName);

    if (!String.IsNullOrEmpty(validationMessage))
    {
    builder.Attributes.Add("title", validationMessage);
    }
    else if (modelError != null)
    {
    builder.Attributes.Add("title", GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, modelError, modelState));
    }

    if (formContext != null)
    {
    bool replaceValidationMessageContents = String.IsNullOrEmpty(validationMessage);

    if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled)
    {
    builder.MergeAttribute("data-valmsg-for", modelName);
    builder.MergeAttribute("data-valmsg-replace", replaceValidationMessageContents.ToString().ToLowerInvariant());
    builder.MergeAttribute("data-val-usetitle", "true");
    }
    else
    {
    FieldValidationMetadata fieldMetadata = ApplyFieldValidationMetadata(htmlHelper, modelMetadata, modelName);
    // rules will already have been written to the metadata object
    fieldMetadata.ReplaceValidationMessageContents = replaceValidationMessageContents; // only replace contents if no explicit message was specified

    // client validation always requires an ID
    builder.GenerateId(modelName + "_validationMessage");
    fieldMetadata.ValidationMessageId = builder.Attributes["id"];
    }
    }

    return builder.ToMvcHtmlString(TagRenderMode.Normal);
    }
    }

    internal static class TagBuilderExtensions
    {
    internal static MvcHtmlString ToMvcHtmlString(this TagBuilder tagBuilder, TagRenderMode renderMode)
    {
    return new MvcHtmlString(tagBuilder.ToString(renderMode));
    }
    }

    关于asp.net-mvc-3 - ASP.NET MVC3 自定义验证消息行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8967809/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com