10

私は 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);
}

nevervalid.js という JavaScript ファイルもあります。

$(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>

ページが読み込まれると、次のファイルが読み込まれます (これは、chrome の 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コードがあるのに、サーバー側の検証を行うためにこれをポストバックしなければならないのですか? 月のない夜、どこかの丘の上で動物を犠牲にしなければならないのですか?

4

1 に答える 1

19

ドキュメントの準備が整う前にコードが実行されるように nevervalid.js を変更するとどうなるか疑問に思っています。

私の基本的な考え方は、dom の準備ができたときにドキュメントを解析することで目立たない検証が機能するということです...しかし、カスタム検証のものを同時に/後でロードしている場合、遭遇したときに何をすべきかわかりません。カスタム検証 data- 属性。

とにかく、nevervalid.js を単に次のように変更してみてください。

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

    $.validator.unobtrusive.adapters.addBool("nevervalid");
})(jQuery);
于 2013-03-20T17:58:04.027 に答える