Как настроить Html.ValidationMessageFor в ASP MVC - PullRequest
21 голосов
/ 05 декабря 2011

Можно ли настроить метод Html.ValidationMessageFor, чтобы он генерировал другой HTML?

Я хочу сделать что-то похожее на:

<div class="field-error-box">
    <div class="top"></div>
    <div class="mid"><p>This field is required.</p></div>
</div>

Ответы [ 6 ]

28 голосов
/ 05 декабря 2011

Я не уверен, возможно ли использовать p aragraph вместо значения по умолчанию span, поскольку плагин проверки может сделать невозможным размещение сообщений об ошибках. Но для div-ов это просто - вы можете написать собственный помощник html.

Что-то в этом духе ( может потребоваться дальнейшее тестирование / кодирование ). Вам нужно будет включить пространство имен этого метода статического расширения в ваше представление или поместить его в System.Web.Mvc.Html напрямую.

public static class Validator
{
    public static MvcHtmlString MyValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
    {
        TagBuilder containerDivBuilder = new TagBuilder("div");
        containerDivBuilder.AddCssClass("field-error-box");

        TagBuilder topDivBuilder = new TagBuilder("div");
        topDivBuilder.AddCssClass("top");

        TagBuilder midDivBuilder = new TagBuilder("div");
        midDivBuilder.AddCssClass("mid");
        midDivBuilder.InnerHtml = helper.ValidationMessageFor(expression).ToString();

        containerDivBuilder.InnerHtml += topDivBuilder.ToString(TagRenderMode.Normal);
        containerDivBuilder.InnerHtml += midDivBuilder.ToString(TagRenderMode.Normal);

        return MvcHtmlString.Create(containerDivBuilder.ToString(TagRenderMode.Normal));
    }
}

Как видите, здесь используется метод ValidationMessageFor по умолчанию, чтобы не мешать обработке сообщений об ошибках плагина проверки.

И вы используете это просто, как вспомогательное средство проверки сообщений по умолчанию

@Html.MyValidationMessageFor(model => model.SomeRequiredField)
7 голосов
/ 02 июня 2013

Я использовал другой способ:

    public static MvcHtmlString DivValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
        return MvcHtmlString.Create(htmlHelper.ValidationMessageFor(expression).ToString().Replace("span", "div"));
    }

Таким образом, вы можете использовать встроенный способ, но заменить span на div.

Если вам нужны другие перегрузки функции, просто дублируйте при необходимости.

3 голосов
/ 05 декабря 2011

Вы можете реализовать свой собственный помощник ValidationMessageFor для создания желаемого результата или использовать некоторый javascript для добавления / изменения отображаемого HTML-кода, но пользовательская реализация ValidationMessageFor является более чистым подходом, IMHO.

Чтобы реализовать свой собственный помощник ValidationMessageFor, взгляните на методы ValidationExtensions.ValidationMessageFor и ValidationMessageHelper в исходном коде ASP.NET MVC.

Советы по реализации

Поскольку GetFormContextForClientValidation является внутренним, вы должны обойти эту реализацию, дублируя внутреннюю функциональность вашего кода:

FormContext formContext = htmlHelper.ViewContext.ClientValidationEnabled ? htmlHelper.ViewContext.FormContext : null;

Некоторые другие методы являются закрытыми в ValidationExtensions, например, GetUserErrorMessageOrDefault, вам также потребуется продублировать этот код. Чтобы избежать дублирования кода, вы можете позволить ValidationExtentensions.ValidationMessageFor отобразить строку сообщения проверки, заключенную в span, и затем изменить отображаемую строку в соответствии с вашими требованиями. Помните, что «null» возвращается, если не было обнаружено ошибок, и что вам понадобятся атрибуты data- HTML, если у вас включен ненавязчивый JavaScript.

Вы можете скачать исходный код ASP.NET MVC 3 с здесь

2 голосов
/ 25 декабря 2012

Единственная потребность в изменении генерации тега по умолчанию была в моем случае, что поведение в диапазонах приводит к нарушению настройки маржи.

Я решил это с помощью 'display: block'

Может быть, это помогает некоторым людям ..

0 голосов
/ 06 декабря 2015

Может быть, вы можете поставить этот код

string propertyName = ExpressionHelper.GetExpressionText(expression);
string name = helper.AttributeEncode(helper.ViewData.TemplateInfo.GetFullHtmlFieldName(propertyName));

if (helper.ViewData.ModelState[name] == null ||
    helper.ViewData.ModelState[name].Errors == null ||
    helper.ViewData.ModelState[name].Errors.Count == 0)
    {
        return MvcHtmlString.Empty;
    }

поверх отвеченной функции, чтобы div не отображался при загрузке формы.

0 голосов
/ 05 декабря 2011

Да, просто используйте метамодель для поля:

[MetadataType(typeof(YourMetaData))]
public partial class YOURCLASS
{
    [Bind(Exclude = "objID")]
    public class YourMetaData
    {
        [Required(AllowEmptyStrings = false, ErrorMessage = "Please enter a name")]
        public object Name { get; set; }
    }
}

Измените ваше сообщение в поле ErrorMessage :) Надеюсь, что это поможет:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...