1

I am working with a custom validation attribute and want to show my validation message, where I will specify a name like this:

return new ValidationResult(FormatErrorMessage("Hobbies"));

I found this html was there on the page:

<span data-valmsg-replace="true" data-valmsg-for="Hobbies" class="field-validation-valid text-danger"></span>

When I return message from the IsValid function of the ValidationAttribute class like this:

return new ValidationResult(FormatErrorMessage("Hobbies"));

Where I specify the name "Hobbies" then it should be added into

<span data-valmsg-for="Hobbies">

Why was my error message was not added?

If you want me to paste full code then please tell me.

Will Ray
  • 10,621
  • 3
  • 46
  • 61
Mou
  • 15,673
  • 43
  • 156
  • 275

1 Answers1

5

I apologize, I'm not completely sure about your question. However, since you said "give me a clue what kind of mistake I have done," I'm going to go with explaining the approach that I've taken in a project which utilizes the ViewModel and a couple of custom validation-handling methods.

I don't think this is a direct answer to your question, but it should give you enough information to be able to make custom methods that build the HTML with the error message content inside it the way you want if you are using MVC w/ razor.

Utilizing ViewModels in razor for validation

Normally, with .NET MVC razor (you didn't mention which version of MVC you were using), you just utilize attributes in the view model for validation, e.g.

public class MyViewModel {
    [Required(ErrorMessage = "Required")]
    public string Name {get; set;}
}

These automatically get validated on post. This will set the property of the view model "Name" to required, and when the validation fails, the error message will be "Required."

Now, if you are doing some processing server side and doing complex validation that is not easy to setup in attributes, then you can manually add an error to your model, like so (my code for captcha validation):

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

Where "Captcha" is the field name and "Verification Required" is the error message.

Displaying Custom Error Messages

Then, stepping away from the standard approach, I have some classes that will build the Bootstrap 3 class "has-error" for the form-group and a custom error that wraps the error message in a label:

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;
    }
}

From there, you can use it just like any of the other @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>

Anyway, I hope that helps you with what you are trying to do. If this is so far away from an answer to your problem, please let me know and I'll remove the answer.

Applying to your HTML requirements:

Oh, and I guess to build the HTML the way you are wanting to, doing it this way, the extension method would look like this:

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;
}

The above method will create your tag regardless, and it will populate it with the first error it finds if there are any errors for that field name.

Kevin Nelson
  • 7,613
  • 4
  • 31
  • 42
  • this line `return new ValidationResult(FormatErrorMessage("Hobbies"));` return error from isValid function of validation attribute and i thought if i mention name then validation message will appear there. but nothing comes......i definitely mistake something. – Mou Mar 28 '16 at 15:19
  • `@Html.ErrorLabel` is any custom helper function or inbuilt ? – Mou Mar 28 '16 at 15:21
  • @Mou, That's an extension method. I just posted at the very bottom an example extension method that would build the tag the way that you want. Extension methods must be in a STATIC class, BTW...you can't just stick it anywhere. – Kevin Nelson Mar 28 '16 at 15:22
  • @Mou, if you use the ViewModel approach in MVC razor, your ValidationResults are automatically placed in your model, so you don't need to return them. Are you using MVC razor or an older version of MVC? – Kevin Nelson Mar 28 '16 at 15:28
  • @Mou, sorry I realized my method for applying it to your HTML wouldn't output the HTML at all unless there was an error. However, since it appears you are using client-side validation, you need the tag to exist even when there is no error. So, I fixed that and the tag will always be there for a fieldName that exists in the view model. – Kevin Nelson Mar 28 '16 at 15:46
  • How to access `ModelState.AddModelError()` from IsValid function of ValidationAttribute class ? – Mou Mar 28 '16 at 18:14
  • @Mou, you don't need to. The attributes in your ViewModel will automatically load the ModelState with your errors. Maybe this will help: http://stackoverflow.com/questions/28090143/best-practices-viewmodel-validation-in-asp-net-mvc – Kevin Nelson Mar 28 '16 at 21:23