2013-05-19 77 views
6

客戶端驗證不Ajax.BeginFormAjax.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" [email protected] 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> 

關於第一個第二個問題, 我的行動是

[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); 


     } 

如果模型是有效的我返回一個局部視圖和頁面看起來很好,否則我返回主視圖,表單,但在這該頁面將自我呈現兩次。問題是,如果客戶端驗證失敗,如何返回帶有驗證錯誤的主窗體?

任何幫助,將不勝感激, 10X羅尼

回答

5

我想通了...... 你應該對結果和查詢有部分看法。

如果失敗,您應該返回「http錯誤請求」並使用以下命令在搜索部分視圖中設置驗證。

這是應該的樣子:

 @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" [email protected] 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); 
    } 
3

當你的ModelState是無效的,你用含誤差模型返回視圖,通過服務器發送的響應具有200 HTTP狀態表明請求成功了。在這種情況下,ajax表單執行您指示它執行的操作,即將返回的響應插入除法repostContent(您可以通過檢查該頁面的第二次呈現是否在該div內完成來驗證)。至於如何讓ajax提交表單與正常表單提交一樣,就顯示驗證信息而言,我還沒有找到一個簡單直接的方法(也許有人可以在這裏爲我們指出一個:)。我通過以下方式解決了這個問題:

  1. 將窗體呈現爲呈現爲主視圖的div(formDiv)的局部視圖。
  2. 有一個「onFailure處」 ajax的形式指定插入響應文本到包含原始形式(formDiv)
  3. 覆蓋OnActionExecuted(因爲我有我的所有其他的繼承主控制器這是div只在一個地方完成)來檢查請求IsAjax和ModelState是否無效,我將響應狀態更改爲4xx。這會導致「OnFailure」被替換爲原來的窗體,並返回If(!ModelState.Isvalid)分支內的窗體。
+0

感謝給我的命中解決呢:) – ron