Пользовательский HTML-помощник для проверки сообщений - PullRequest
0 голосов
/ 28 ноября 2018

Я написал собственный тег HTTML Helper для вывода сообщений проверки.Он работает должным образом, но всегда присутствует.

@Html.MyValidationMsg(m => m.FirstName)

public static IHtmlContent MyValidationMsg<TModel, TProperty>(this IHtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
    {
        MemberExpression memberExpression = expression.Body as MemberExpression;

        var reqAttrib = memberExpression.Member
                      .GetCustomAttributes(typeof(RequiredAttribute), false)
                      .Cast<RequiredAttribute>()
                      .SingleOrDefault();

        var displayAttrib = memberExpression.Member
                      .GetCustomAttributes(typeof(DisplayAttribute), false)
                      .Cast<DisplayAttribute>()
                      .SingleOrDefault();

        var errMsg = reqAttrib.ErrorMessage ?? displayAttrib.Name + " is required.";

        var content = new HtmlContentBuilder()
                 .AppendHtml("<div class=\"rvt-inline-alert rvt-inline-alert--standalone rvt-inline-alert--danger\">")
                 .AppendHtml("<span class=\"rvt-inline-alert__icon\">")
                 .AppendHtml("<svg aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\">")
                .AppendHtml("<g fill=\"currentColor\">")
                .AppendHtml("<path d=\"M8,0a8,8,0,1,0,8,8A8,8,0,0,0,8,0ZM8,14a6,6,0,1,1,6-6A6,6,0,0,1,8,14Z\" />")
                .AppendHtml("<path d=\"M10.83,5.17a1,1,0,0,0-1.41,0L8,6.59,6.59,5.17A1,1,0,0,0,5.17,6.59L6.59,8,5.17,9.41a1,1,0,1,0,1.41,1.41L8,9.41l1.41,1.41a1,1,0,0,0,1.41-1.41L9.41,8l1.41-1.41A1,1,0,0,0,10.83,5.17Z\"/>")
                .AppendHtml("</g>")
                .AppendHtml("</svg>")
                .AppendHtml("</span>")
                .AppendHtml("<span class=\"rvt-inline-alert__message\" role=\"alert\" id=\"radio-list-message\">")
                .AppendHtml(errMsg)
                .AppendHtml("</span>")
                .AppendHtml("</div>");
        return content;
    }

Как бы я скрыл его при начальной загрузке страницы бритвы и, когда поле недействительно, чтобы оно появилось?

Спасибо за помощь

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

ОГРОМНОЕ СПАСИБО @ itminus за то, что нашли время, чтобы вывести меня на правильный путь.

Я закончил тем, что полностью искал этот путь в пользу переопределения jquery.validate.Также манипулировал DOM с помощью javascript / jquery для получения желаемого результата.

Требуемый вывод для сообщения об ошибке:

<div class="rvt-inline-alert rvt-inline-alert--danger">
    <span class="rvt-inline-alert__icon">
        <svg width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">
            <g fill="currentColor">
                <path d="M8,0a8,8,0,1,0,8,8A8,8,0,0,0,8,0ZM8,14a6,6,0,1,1,6-6A6,6,0,0,1,8,14Z"/>
                <path d="M10.83,5.17a1,1,0,0,0-1.41,0L8,6.59,6.59,5.17A1,1,0,0,0,5.17,6.59L6.59,8,5.17,9.41a1,1,0,1,0,1.41,1.41L8,9.41l1.41,1.41a1,1,0,0,0,1.41-1.41L9.41,8l1.41-1.41A1,1,0,0,0,10.83,5.17Z"/>
            </g>
        </svg>
    </span>
    <span class="rvt-inline-alert__message" role="alert">Your Name is required.</span>
</div>

Код в _ValidationScriptsPartial.cshtml, чтобы творить чудеса:

<script type="text/javascript">
    var settings = {
        errorElement: "span",
        errorClass: "rvt-validation-danger", //around textbox on error
        errorPlacement: function (error, element) {

            var avg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
            avg.setAttribute("width", "16");
            avg.setAttribute("height", "16");
            avg.setAttribute("viewBox", "0 0 16 16");
            avg.setAttribute("aria-hidden", "true");

            var g = document.createElement("g");
            g.setAttribute("fill", "currentColor");

            var p1 = document.createElement("path");
            p1.setAttribute("d", "M8,0a8,8,0,1,0,8,8A8,8,0,0,0,8,0ZM8,14a6,6,0,1,1,6-6A6,6,0,0,1,8,14Z");

            var p2 = document.createElement("path");
            p2.setAttribute("d", "M10.83,5.17a1,1,0,0,0-1.41,0L8,6.59,6.59,5.17A1,1,0,0,0,5.17,6.59L6.59,8,5.17,9.41a1,1,0,1,0,1.41,1.41L8,9.41l1.41,1.41a1,1,0,0,0,1.41-1.41L9.41,8l1.41-1.41A1,1,0,0,0,10.83,5.17Z");

            g.appendChild(p1);
            g.appendChild(p2);
            avg.appendChild(g);   

            var spanIcon = document.createElement("span");
            spanIcon.setAttribute("class", "rvt-inline-alert__icon");
            spanIcon.innerHTML += avg.outerHTML;

            var spanMsg = document.createElement("span");
            spanMsg.setAttribute("class", "rvt-inline-alert__message");
            spanMsg.setAttribute("role", "alert");
            spanMsg.innerHTML += error[0].innerHTML;           

            var c = document.createElement("div");
            c.setAttribute("class", "rvt-inline-alert rvt-inline-alert--danger");
            c.innerHTML += spanIcon.outerHTML + spanMsg.outerHTML;
            error.replaceWith(c);
        }
    };

    $.validator.unobtrusive.options = settings;
</script>
0 голосов
/ 29 ноября 2018

Существует две причины, по которым сообщение всегда появляется.

  1. Как сказал @Sonal Borkar, первая причина в том, что var errMsg = reqAttrib.ErrorMessage ?? displayAttrib.Name + " is required." заставляет его возвращать какое-то значение, даже еслиатрибута [Required] нет .

    Но не меняйте его на var errMsg = reqAttrib.ErrorMessage != null ? displayAttrib.Name + " is required.", потому что reqAttrib может быть null.Вместо этого вы можете изменить код следующим образом:

    var errMsg = reqAttrib==null ? 
        "": 
        reqAttrib?.ErrorMessage ?? displayName + " is required.";
    
  2. Во-вторых, вы забыли проверить, имеет ли текущее свойство значение .Предположим, у нас есть свойство с оформленным атрибутом [Required], и ему присвоено значение, поэтому мы не должны отображать требуемое сообщение, например «xxx is required».

Кроме того,в вашем коде есть и другие ошибки null object reference:

    var displayAttrib = memberExpression.Member
            .GetCustomAttributes(typeof(DisplayAttribute), false)    
            .Cast<DisplayAttribute>()
            .SingleOrDefault();                                      

    var errMsg = reqAttrib.ErrorMessage ?? displayAttrib.Name + " is required.";
  • reqAttrib может быть null, поэтому reqAttrib.ErrorMessage может выдавать ошибки.
  • displayAttrib может быть null тоже
  • , если displayAttrib равно нулю, мы должны вернуться к memberExpression.Member.Name

Чтобы исправить ошибки, измените свой код какниже:

    public static IHtmlContent MyValidationMsg<TModel, TProperty>(this IHtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
    {
        MemberExpression memberExpression = expression.Body as MemberExpression;

        var reqAttrib = memberExpression.Member
                    .GetCustomAttributes(typeof(RequiredAttribute), false)
                    .Cast<RequiredAttribute>()
                    .SingleOrDefault();

        var contentBuilder = new HtmlContentBuilder();
        // if the current property has no [Required] attribute, there's no need to display required message 
        if(reqAttrib == null ){return contentBuilder; }


        // check the value of current property 
        var compiled = expression.Compile();
        var model = (TModel) helper.ViewData.Model ;
        if(model == null){ 
            throw new Exception("No Model associated with the view !"); 
        }
        var propValue = (TProperty) compiled.Invoke(model);        
        // I just test nullable props here, you might custom it to fulfill your requirements, eg : whether the length of string matches
        if(propValue != null){ return contentBuilder; }


        var member = memberExpression.Member;
        var displayName= member
                    .GetCustomAttributes(typeof(DisplayAttribute), false)
                    .Cast<DisplayAttribute>()
                    .SingleOrDefault()
                    ?.Name             // might be null
                    ?? member.Name;    // fall back
        var errMsg = reqAttrib==null ? 
            "": 
            reqAttrib?.ErrorMessage ?? displayName + " is required.";
        if(String.IsNullOrEmpty(errMsg)){ return contentBuilder; }
        return contentBuilder
                .AppendHtml("<div class=\"rvt-inline-alert rvt-inline-alert--standalone rvt-inline-alert--danger\">")
                .AppendHtml("<span class=\"rvt-inline-alert__icon\">")
                .AppendHtml("<svg aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\">")
                .AppendHtml("<g fill=\"currentColor\">")
                .AppendHtml("<path d=\"M8,0a8,8,0,1,0,8,8A8,8,0,0,0,8,0ZM8,14a6,6,0,1,1,6-6A6,6,0,0,1,8,14Z\" />")
                .AppendHtml("<path d=\"M10.83,5.17a1,1,0,0,0-1.41,0L8,6.59,6.59,5.17A1,1,0,0,0,5.17,6.59L6.59,8,5.17,9.41a1,1,0,1,0,1.41,1.41L8,9.41l1.41,1.41a1,1,0,0,0,1.41-1.41L9.41,8l1.41-1.41A1,1,0,0,0,10.83,5.17Z\"/>")
                .AppendHtml("</g>")
                .AppendHtml("</svg>")
                .AppendHtml("</span>")
                .AppendHtml("<span class=\"rvt-inline-alert__message\" role=\"alert\" id=\"radio-list-message\">")
                .AppendHtml(errMsg)
                .AppendHtml("</span>")
                .AppendHtml("</div>");
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...