Skip to content

Instantly share code, notes, and snippets.

@davidisnotnull
Created May 23, 2018 10:49
Show Gist options
  • Save davidisnotnull/51f9ff8ef8e687efeb825977464d5924 to your computer and use it in GitHub Desktop.
Save davidisnotnull/51f9ff8ef8e687efeb825977464d5924 to your computer and use it in GitHub Desktop.
MVC Validation Message Extension
// This class allows for HTML to be used in ValidationResult error messages within
// the ViewModel. You call it using CustomValidationMessageFor(m => m.Property)
public static class ValidationMessageExtensions
{
public static IHtmlString CustomValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> ex)
{
var htmlAttributes = new RouteValueDictionary();
string validationMessage = null;
var expression = ExpressionHelper.GetExpressionText(ex);
var modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
var formContext = htmlHelper.ViewContext.ClientValidationEnabled ? htmlHelper.ViewContext.FormContext : null;
if (!htmlHelper.ViewData.ModelState.ContainsKey(modelName) && formContext == null)
return null;
var modelState = htmlHelper.ViewData.ModelState[modelName];
var modelErrors = (modelState == null) ? null : modelState.Errors;
var modelError = (((modelErrors == null) || (modelErrors.Count == 0))
? null
: modelErrors.FirstOrDefault(m => !string.IsNullOrEmpty(m.ErrorMessage)) ?? modelErrors[0]);
if (modelError == null && formContext == null)
return null;
var builder = new TagBuilder("span");
builder.MergeAttributes(htmlAttributes);
builder.AddCssClass((modelError != null) ? HtmlHelper.ValidationMessageCssClassName : HtmlHelper.ValidationMessageValidCssClassName);
if (!string.IsNullOrEmpty(validationMessage))
builder.InnerHtml = validationMessage;
else if (modelError != null)
builder.InnerHtml = GetUserErrorMessageOrDefault(htmlHelper.ViewContext.HttpContext, modelError, modelState);
if (formContext != null)
{
bool replaceValidationMessageContents = string.IsNullOrEmpty(validationMessage);
builder.MergeAttribute("data-valmsg-for", modelName);
builder.MergeAttribute("data-valmsg-replace", replaceValidationMessageContents.ToString().ToLowerInvariant());
}
return new HtmlString(builder.ToString(TagRenderMode.Normal));
}
private static string GetUserErrorMessageOrDefault(HttpContextBase httpContext, ModelError error, ModelState modelState)
{
if (!string.IsNullOrEmpty(error.ErrorMessage))
return error.ErrorMessage;
if (modelState == null)
return null;
var attemptedValue = (modelState.Value != null) ? modelState.Value.AttemptedValue : null;
return string.Format(CultureInfo.CurrentCulture, "Value '{0}' not valid for property", attemptedValue);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment