如何从服务器端验证属性插入自定义错误消息

Mou*_*Mou 1 validation asp.net-mvc

我正在使用自定义验证属性并希望显示我的验证消息,我将在其中指定一个名称,如下所示:

return new ValidationResult(FormatErrorMessage("Hobbies"));
Run Code Online (Sandbox Code Playgroud)

我发现这个 html 在页面上:

<span data-valmsg-replace="true" data-valmsg-for="Hobbies" class="field-validation-valid text-danger"></span>
Run Code Online (Sandbox Code Playgroud)

当我像这样从类的IsValid函数返回消息时ValidationAttribute

return new ValidationResult(FormatErrorMessage("Hobbies"));
Run Code Online (Sandbox Code Playgroud)

在我指定名称“爱好”的地方,应该将其添加到

<span data-valmsg-for="Hobbies">
Run Code Online (Sandbox Code Playgroud)

为什么没有添加我的错误信息?

如果你想让我粘贴完整的代码,请告诉我。

Kev*_*son 5

我很抱歉,我不完全确定你的问题。但是,既然您说“请告诉我我犯了什么样的错误”,我将继续解释我在使用 ViewModel 和一些自定义验证处理方法的项目中采用的方法.

我不认为这是您问题的直接答案,但它应该为您提供足够的信息,以便能够制作自定义方法,如果您使用 MVC w/剃刀

在 razor 中使用 ViewModels 进行验证

通常,使用 .NET MVC razor(您没有提到您使用的是哪个版本的 MVC),您只需利用视图模型中的属性进行验证,例如

public class MyViewModel {
    [Required(ErrorMessage = "Required")]
    public string Name {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

这些会在发布时自动得到验证。这会将视图模型“Name”的属性设置为required,当验证失败时,错误信息将是“Required”。

现在,如果您正在做一些处理服务器端并在属性中进行不容易设置的复杂验证,那么您可以手动向模型添加错误,如下所示(我的验证码验证代码):

//inside controller HttpPost method
var isCaptchaValid = ReCaptcha.IsCaptchaValid(Request.Form["g-recaptcha-response"] ?? "");
if (!isCaptchaValid)
{
    ModelState.AddModelError("Captcha", "Verification Required");
}
Run Code Online (Sandbox Code Playgroud)

其中“Captcha”是字段名称,“Verification Required”是错误消息。

显示自定义错误消息

然后,远离标准方法,我有一些类将为表单组构建 Bootstrap 3 类“has-error”和一个将错误消息包装在标签中的自定义错误:

public static class HtmlExtensions {
    public static string GetErrorClass(this HtmlHelper htmlHelper, bool hasError)
    {
        return " has-error";
    }
    public static MvcHtmlString ErrorLabel<TModel>(this HtmlHelper<TModel> helper, ModelStateDictionary modelState, string fieldName)
    {
        if (modelState[fieldName] != null )
        {
            var error = modelState[fieldName].Errors.FirstOrDefault();
            if (error != null)
            {
                var span = new TagBuilder("span");
                span.AddCssClass("label label-danger");
                span.InnerHtml = error.ErrorMessage;
                return MvcHtmlString.Create(span.ToString(TagRenderMode.Normal));
            }
        }
        return MvcHtmlString.Empty;
    }
}
Run Code Online (Sandbox Code Playgroud)

从那里,您可以像任何其他@Html 一样使用它

<div class='form-group@Html.GetErrorClass("Name")'>
    <label class='control-label col-xs-12 col-sm-6' for='name'>@Html.ErrorLabel(ViewData.ModelState,"Name") Name:</label>
    <div class='col-xs-12 col-sm-6'>
        @Html.TextBoxFor(model => model.Name, new { @class = "form-control" })
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

无论如何,我希望这对您正在尝试做的事情有所帮助。如果这与您的问题的答案相去甚远,请告诉我,我将删除答案。

适用于您的 HTML 要求:

哦,我想按照你想要的方式构建 HTML,这样做,扩展方法看起来像这样:

public static MvcHtmlString MyErrorExtension<TModel>(this HtmlHelper<TModel> helper, ModelStateDictionary modelState, string fieldName)
{
    if (modelState[fieldName] != null)
    {
        var error = modelState[fieldName].Errors.FirstOrDefault();

        //<span data-valmsg-replace="true" data-valmsg-for="Hobbies" class="field-validation-valid text-danger"></span>
        var span = new TagBuilder("span");
        span.Attributes.Add("data-valmsg-replace", "true");
        span.Attributes.Add("data-valmsg-for", fieldName);
        span.AddCssClass("field-validation-valid text-danger");

        if (error != null)
        {
            span.InnerHtml = error.ErrorMessage;
        }
        return MvcHtmlString.Create(span.ToString(TagRenderMode.Normal));
    }
    return MvcHtmlString.Empty;
}
Run Code Online (Sandbox Code Playgroud)

无论如何,上述方法都会创建您的标签,如果该字段名称有任何错误,它将用它找到的第一个错误填充它。