2013-10-28 80 views
0

這是一個很明顯的話題,但我一直沒有能夠想出一個解決方案,閱讀以前的職位。希望有人能告訴我這樣做的「正確方法」,因爲我需要做很多工作。Ajax.Beginform後驗證時,Model.State無效觸發器OnSuccess函數

主要問題:當Ajax.Beginform發佈ModelState無效時,它仍會觸發OnSuccess方法。我知道這是正確的行爲,但是我的OnSuccess方法只會在(去圖)帖子「成功」時纔有意義。

在這種情況下,如何最好地管理帶驗證錯誤的重新顯示錶單?如何從我的控制器返回成功= false以及要重新顯示的視圖?

這與問題沒有特別的相關性,但是我在這裏做的事情與試圖在Bootstrap Modal中顯示錶單的方式有些類似,我放棄了這種方式。

1)通過ajax調用控制器以div形式加載表單。

$(function addpaneevent() { 
    $('.addpane').on("click", function() { 
     var url = '/QuizPane/QuickPane?quizId=' + $(this).data("quizid"); 
     $.ajax({ 
      url: url, 
      type: 'GET', 
      contentType: 'application/json', 
      success: function (result) { 
       $('#overlay').html(result); 
      }, 
      error: function (result) { 
       console.log("bummer",result); 
      } 
     }); 
    }); 
}); 

2)返回包含局部視圖形式

public ActionResult QuickPane(int quizId) 
{ 
    var model = *querytogetmodel* 
    return PartialView("QuickPane",model); 
} 


@using (Ajax.BeginForm("QuickPane", "QuizPane", FormMethod.Post, 
    new AjaxOptions 
    { 
          InsertionMode = InsertionMode.Replace, 
          HttpMethod = "POST", 
          OnSuccess = "updatePaneList(data)", 
          OnFailure = "massivefail(data)", 
    })) 
{ 
    @Html.ValidationSummary(true) 

    <fieldset> 
     @Html.HiddenFor(model => model.QuizID) 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Title) 
     </div> 
     <div class="editor-field"> 
      @Html.TextBoxFor(model => model.Title, new { @autofocus = "autofocus" }) 
      @Html.ValidationMessageFor(model => model.Title) 
     </div> 
     ...more of the same 
     <input type="submit" value="Create" class="btn btn-primary"/> 
    </fieldset> 
} 

3)在提交呼叫交

[HttpPost] 
public ActionResult QuickPane(QuizPane quizpane) 
{ 
    if (ModelState.IsValid) 
    { 
     db.QuizPanes.Add(quizpane); 
     db.SaveChanges(); 
     return PartialView("_quizpanelist", quizpane); 
    } 
    return View(quizpane); //tried a few different things here 
} 

4)在成功我添加新的記錄到表和除去包含輸入表單的div。

function updatePaneList(data) { 
    $("#overlay").remove(); 
    var rowcount = $(".expanded #panetable tr:last").count; 
    $('.expanded #panetable tbody:last').append(data);   
}; 

回答

0

而不是使用Ajax.BeginForm我會使用一個正常的形式,並使用ajax調用這個。

$(document).on('click', '.btn-primary', function(){ 
    $.ajax({ 
     url: '@Url.Action('QuickPane', 'QuizPane')', 
     type: 'post', 
     data: { 
      Title: $('#Title').val() 
     } 
     success: function(result){ 
      //Do Something 
     } 
     error: function(result){ 
      //Display error 
     } 
    }); 
}); 

然後在你的控制器返回JSON而不是局部視圖,你可以設置錯誤這樣return Json error from ASP.NET MVC或成功這樣ExtJS: how to return json success w/ data using asp.net mvc 希望這有助於。

+0

在這種情況下,不是我失去了模型驗證的所有優點,並附帶消息需要領域等?爲什麼一切都必須如此艱難? :) – Joel

+0

我已成功獲取驗證以顯示部分視圖的唯一方法是將其更改爲完整視圖並將其顯示在iframe中。您可以使用此方法執行客戶端jQuery驗證,並手動執行服務器端驗證,並通過錯誤發送結果,但這有點多。這對我來說也是一個棘手的情況 –

+0

我編輯我的問題,因爲我實際上做返回視圖(quizpane);而不是PartialView。 如果我將UpdateTargetId =「overlay」添加到我的Ajax.BeginForm,它會在ModelState.IsValid == false時正確驗證。但是,當ModelState.IsValid == true時它失敗,因爲它從不調用OnSuccess方法,它只是將結果插入到我不想要的#overlay中。 如果我刪除UpdateTargetId =「overlay」,它將在ModelState.IsValid == true時正常工作,但在ModelState.IsValid == false時失敗,因爲我沒有在窗體中獲取驗證錯誤。 Jeebus! – Joel

3

我通過執行以下操作來解決此問題...雖然我不知道這是否是一種建議的方式來處理它。另外,您應該在兩種情況下都返回部分視圖。

之前返回局部視圖中添加以下行

Response.AppendHeader("X-Error", "true") 

然後,在JavaScript的onSuccess

function doOnSuccess(data, status, xhr) { 
    if (xhr.getResponseHeader('X-Error')) { 
     //validation error occurred 
    } 
    else 
    { 
     //validation error did not occur 
    } 
} 
+0

瑞恩,我剛剛看到了這個迴應,我的道歉。 我最終做了一些不同的事情,雖然真的和你建議的一樣。如果驗證失敗,我會得到與驗證錯誤相同的表單。如果帖子成功,我會看到成功的觀點。因此,在javascript成功函數中,我添加了 if(data.indexOf(「form action =」)=== -1){// success stuff)else { //重新顯示錶格 } – Joel

0

這是因爲OnSuccess VS OnFailure沒有以任何方式掛接到ModeState.IsValid

AjaxOptions docs

OnSuccess:如果響應狀態是在200範圍調用此函數。
OnFailure:如果在200範圍內的響應狀態不是,則會調用此函數。

換句話說,你必須手動指定,通過改變Response.StatusCode回你的ActionResult時,然後再返回你在你的OnFailure js的方法期待的任何值出現了故障。

[HttpPost] 
public ActionResult Search(Person model) 
{ 
    if (ModelState.IsValid) { 
    // if valid, return a HTML view inserted by AJAX helper 
    var results = PersonRepository.Get(model) 
    return PartialView("Resulsts", vm); 

    } else { 
    // if invalid, return a JSON object and handle with OnFailure method 
    Response.StatusCode = (int)HttpStatusCode.BadRequest; 
    return Json(new { errors = ModelState.Values.SelectMany(v => v.Errors) }); 

    } 
} 

進一步閱讀

相關問題