10

Ajax.BeginForm でクライアント側の検証が機能しない

これは私のコードです:

<div id="report">
    <div id="projectReport">
        <div >
            @{
                Html.EnableClientValidation();
            }

            @using (Ajax.BeginForm("AnalyticsDates", new AjaxOptions
                {
                    InsertionMode = InsertionMode.Replace,
                    UpdateTargetId = "reportContent"
                }))
            {
                @Html.LabelFor(m => m.StartDate)
                @Html.TextBoxFor(m => m.StartDate, new { id = "start" })
                @Html.ValidationMessageFor(model => model.StartDate)
                @Html.LabelFor(m => m.EndDate)
                @Html.TextBoxFor(m => m.EndDate, new { id = "end" })
                @Html.ValidationMessageFor(model => model.EndDate)
                <input id="btnsearch" type="submit" value=@Titles.Search class="iconHeader"/>
            }
        </div>
    </div>
    <div id="reportContent">
    </div>
</div>

そして、web.config ページで検証を有効にしました。

<add key="ClientValidationEnabled" value="true" />   
<add key="UnobtrusiveJavaScriptEnabled" value="true" />

jsファイルも追加しました

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>

最初の問題に関連する2番目の問題、私の行動は

[HttpPost]
        [Authorize(Roles = "XXXReport")]
        public async Task<ActionResult> AnalyticsDates(ReportRequestVM reportRequestVM)
        {
            if (!ModelState.IsValid)
            {
                return View("**MainReports**", reportRequestVM);
            }

            // fill reportRequestVM with data
            return View("**PartialReport**", reportRequestVM);


        }

モデルが有効な場合は、部分ビューを返し、ページは正常に見えます。それ以外の場合は、メイン ビューとフォームを返しますが、この場合、ページはそれ自体を 2 回レンダリングします。問題は、クライアントの検証が失敗した場合に、検証エラーを含むメイン フォームを返す方法です。

助けていただければ幸いです、10x Rony

4

2 に答える 2

6

私はそれを理解しました...結果とクエリの部分的なビューが必要です。

失敗した場合は、「http bad request」を返し、次を使用して検索部分ビューで検証を設定する必要があります。

これはどのように見えるべきかです:

        @using (Ajax.BeginForm("CloudAnalyticsDates", new AjaxOptions
            {
                InsertionMode = InsertionMode.Replace,
                UpdateTargetId = "reportContent",
                OnFailure = "OnCloudAnalyticsFailure",
                OnBegin = "ValidateForm",


            }))
        {
            @Html.LabelFor(m => m.StartDate)
            @Html.TextBoxFor(m => m.StartDate, new { id = "start" })
            @Html.ValidationMessageFor(model => model.StartDate)
            @Html.LabelFor(m => m.EndDate)
            @Html.TextBoxFor(m => m.EndDate, new { id = "end" })
            @Html.ValidationMessageFor(model => model.EndDate)
            <input id="btnsearch" type="submit" value=@Titles.Search class="iconHeader"/>
        }
    </div>
</div>

<script type="text/javascript">
    $(document).ready(function () {
        $("#datePicker").kendoDatePicker();
        $("#start").kendoDatePicker().data("kendoDatePicker");
        $("#end").kendoDatePicker().data("kendoDatePicker");
    });


    function OnCloudAnalyticsFailure(parameters) {

        $('#projectReport').html(parameters.responseText);
        $('#reportContent').empty();
        CleanValidationError('form');
    }



</script>

サーバー上では次のようになります。

[HttpPost]

    public async Task<ActionResult> CloudAnalyticsDates(ReportRequestVM reportRequestVM)
    {
        if (!ModelState.IsValid)
        {
            Response.StatusCode = (int)HttpStatusCode.BadRequest;
            return PartialView("_ReportQuery", reportRequestVM);
        }


        reportRequestVM.BomTotals = await CommonRequestsHelper.GetBomTotalAnalytics(bomTotalRequest);
        return PartialView("_ProjectReport", reportRequestVM);
    }
于 2013-05-22T07:13:07.000 に答える
3

When your modelstate is invalid and you return the view with the model containing the errors, the response sent by the server has an http status of 200 indicating that the request succeeded. In this case, the ajax form does what you instructed it to do which is to insert the returned response into division repostContent (you can verify that by checking that the second rendering of the page is done inside that div). As to how to get an ajax submit form to act the same as normal form submission as far as displaying validation messages, I have not found a simple straight forward method (maybe someone can point one out here :) for us). I solved this by:

  1. Having the form in a partial view rendered into a div (formDiv) of the main view.
  2. Having a "OnFailure" specified on the ajax form that inserts the response text into the div that contained the original form (formDiv)
  3. Override OnActionExecuted (since I have a main controller that all my other ones inherit from this is done in only one place) to check if a request IsAjax and ModelState is invalid, I change the response status to 4xx. This causes the "OnFailure" to get fired replacing the original form with the one returned inside the If(!ModelState.Isvalid) branch.
于 2013-05-19T14:36:34.457 に答える