ASP.NET MVC 4 — проверка на стороне клиента не работает

Я использую Visual Studio 2012, и я не могу заставить логику пользовательской стороны атрибута работать для воспроизведения в меньшем масштабе, я создал новый проект MVC 4. Я создал следующую модель и атрибут, которые никогда не будут проверяться

public class MyModel
{
    public int Id { get; set; }
    [Required]
    public string LastName { get; set; }
    [NeverValid(ErrorMessage="Serverside Will Never Validate")]
    public string FirstName { get; set; }
}

public class NeverValidAttribute : ValidationAttribute, IClientValidatable
{
    public override bool IsValid(object value)
    {
        return false;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        return new ValidationResult(this.ErrorMessage, new[] { validationContext.MemberName });
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRule
        {
            ErrorMessage = this.ErrorMessage,
            ValidationType = "nevervalid"
        };
    }
}

Затем я добавляю следующие действия в HomeController

public ActionResult Index()
{
    return View(new MyModel());
}

[HttpPost]
public ActionResult Index(MyModel model)
{
    if (!ModelState.IsValid)
    {
        // Will Always Be Invalid
    }

    return View(model);
}

Существует также файл javascript с именем nevervalid.js.

$(function () {
    $.validator.addMethod("nevervalid", function () {
        return false;
    }, "Clientside Should Not Postback");

    $.validator.unobtrusive.adapters.addBool("nevervalid");
});

и представление индекса

@model CustomAttribute.Models.MyModel

@{
    ViewBag.Title = "Home Page";
}

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>MyModel</legend>

        @Html.HiddenFor(model => model.Id)

        <div class="editor-label">
            @Html.LabelFor(model => model.LastName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.FirstName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.FirstName)
            @Html.ValidationMessageFor(model => model.FirstName)
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/Scripts/nevervalid.js")
}

Соответствующие области в моем web.config выглядят так

<appSettings>
    <add key="webpages:Version" value="2.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="PreserveLoginUrl" value="true" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

когда страница загружается, загружаются следующие файлы (получил это на вкладке сети под хром F12)

http://localhost:7440/
http://localhost:7440/Content/site.css
http://localhost:7440/Scripts/modernizr-2.5.3.js
http://localhost:7440/Scripts/jquery-1.7.1.js
http://localhost:7440/Scripts/jquery.unobtrusive-ajax.js
http://localhost:7440/Scripts/jquery.validate.js
http://localhost:7440/Scripts/jquery.validate.unobtrusive.js
http://localhost:7440/Scripts/nevervalid.js

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

    <input class="text-box single-line valid" data-val="true" data-val-nevervalid="Serverside Will Never Validate" id="FirstName" name="FirstName" type="text" value="">

Итак, я спрашиваю вас, почему, почему эта штука должна выполнять обратную передачу для проверки на стороне сервера, в то время как у меня здесь есть прекрасно выглядящий код javascript? я должен принести в жертву какое-то животное в безлунную ночь где-то на вершине холма?


person G2Mula    schedule 20.03.2013    source источник
comment
Помогает ли это, кажется, вы не переопределяете все необходимые функции в своем атрибуте проверки. stackoverflow.com/ вопросы/8284207/   -  person Patrick Magee    schedule 20.03.2013
comment
Привет, Патрик, спасибо, что уделили время рассмотрению проблемы. В спешке, чтобы получить наименьший воспроизводимый код, я упустил из виду второе переопределение IsValid... но оно не работает... Думаю, я уже прошел через это. все связанные вопросы SO. но ничего... Я надеюсь, что кто-то сможет воспроизвести это на своем конце света, подтвердите, что я не схожу с ума...   -  person G2Mula    schedule 20.03.2013


Ответы (1)


Мне интересно, что произойдет, если вы измените nevervalid.js так, чтобы код выполнялся до того, как документ будет готов.

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

В любом случае, попробуйте изменить nevervalid.js так:

(function($) {
    $.validator.addMethod("nevervalid", function () {
        return false;
    }, "Clientside Should Not Postback");

    $.validator.unobtrusive.adapters.addBool("nevervalid");
})(jQuery);
person Charlino    schedule 20.03.2013
comment
да, все еще работает, и редактирование выглядит гораздо менее голым, я слишком долго использую jQuery, и в нем есть кое-что, я забыл спросить, что они на самом деле означают... - person G2Mula; 20.03.2013
comment
Все хорошо, рад, что это решило вашу проблему. Редактирование было просто лучшей практикой :-) - person Charlino; 20.03.2013
comment
Может ли кто-нибудь помочь мне, в чем разница между (function($){})(jQuery) и $(document).ready(function{})?? - person Seyed Morteza Mousavi; 27.09.2013
comment
$(document).ready(function{}) вызывается, когда документ готов (все загружено, купол готов, бла-бла...) (function($){})(jQuery) будет запущен сразу же, как только встретится, это в основном просто функция ($) {}, вызываемая немедленно с jQuery в качестве параметра... надеюсь, это имеет смысл - person G2Mula; 30.09.2013
comment
Большое спасибо @Charlino, после долгих усилий ваш ответ очень полезен для меня. Я хотел бы дать вам больше голосов за ваш ответ. - person Dilip0165; 15.10.2013
comment
Спасибо за это, это очень полезно, я не обращал особого внимания на эту тонкую часть. Однако эта тонкая деталь меняет всю картину. :-) - person Box Very; 09.12.2020