2009-10-09 47 views
6

有一個很多很好的職位,並解釋如何實現驗證與ASP.NET MVC的,我比較喜歡其中的一個:

不過,我真的很喜歡通過jquery $ .ajax方法來調用ActionMethods。我想使用$ .ajax的原因之一是因爲通過$ .ajax調用將動態加載到頁面中的許多部分視圖(甚至是實體創建的表單),並且我不能只返回視圖 - 我將失去所有動態加載的內容。

爲了讓您更好地瞭解問題,我將發佈一些簡單的代碼來解釋如何調用控制器操作並處理客戶端,jQuery代碼中的響應。

的控制器ActionMethod:

public ActionResult CreateCustomer(string name, string accountNumber) 
    { 
     try 
     { 
      CustomerService.InsertCustomer(name, accountNumber); 

      return Json(new ActionInfo() 
      { 
       Success = true, 
       Message = "Customer Is Successfully Created" 
      }); 

     } 
     catch (Exception ex) 
     { 
      return Json(new ActionInfo() 
      { 
       Success = false, 
       Message = ex.Message 
      }); 
     } 
    } 

呼叫和客戶端代碼中處理:

$.ajax({ 
type: "POST", 
url: $form.attr('action'),// /MyController/CreateCustomer 
data: $form.serialize(), 
error: HandleUnespectedError, 
dataType: "json", 
success: function(response) { 

    if (response.Success) 
     alert("Success: " + response.Message); 
    else 
     alert("Error: " + response.Message); 
}}); 

有沒有做一些驗證框架的工作,我需要的方式的好辦法?我知道我可以在ActionInfo中添加驗證錯誤,然後在客戶端處理它,但是我相信這已經是我的一個驗證的構建。

回答

5

我通過使用數據註釋屬性通過AJAX進行驗證取得了巨大的成功。爲了檢查數據的有效性,您需要使用控制器的ModelState屬性,該屬性具有其自己的屬性IsValid。我強烈建議從官方ASP.NET MVC網站上瀏覽一下data annotations validation attributes tutorial

首先,您需要修改控制器操作以接受模型對象作爲參數,而不是單獨的名稱和帳號。這將使執行驗證,我將在下面演示,更簡單。從你的例子中,我最好的猜測是你的模型對象是或將被稱爲Customer。您可能有以下代碼來定義模型對象和控制器的動作......

// model object 
public class Customer 
{ 
    public Int32 Id {get; set;} 
    public String Name {get; set;} 
    public String AccountNumber {get; set;} 
} 

// controller 
public class CustomerController : Controller 
{ 
    public ActionResult CreateCustomer([Bind(Exclude = "Id")] Customer customer) 
    { 
    // controller action code 
    } 
} 


確保您的窗體字段被命名爲匹配客戶對象的屬性,以便ASP的名字.NET MVC可以自動綁定它們。在這種情況下,「綁定」屬性告訴ASP.NET MVC在將表單字段綁定到模型屬性時忽略Customer類的「Id」屬性。由於這是一個新客戶,我們還沒有Id,所以我們可以安全地將Id保留爲默認值,並讓數據層確定如何最好地生成它。

一旦控制器構建了動作方法的模型對象,就可以通過ModelState.IsValid屬性輕鬆檢查其有效性。正如人們所預料的那樣,如果模型屬性有效,它將返回true;如果一個或多個屬性無效,則返回false。

從原始問題看來,CustomerService.InsertCustomer方法在驗證失敗時拋出異常。這完全沒有必要。 InsertCustomer只需要執行插入新記錄所需的任何數據操作。除非你希望抽象實現特定的異常,如SQLException,InsertCustomer應該不是真的需要捕捉或拋出任何異常,但最有可能只是讓任何異常泡到控制器(或誰來電者而定)。

這一切的最終結果,可能是一個控制器動作,看起來像下面這樣:

public ActionResult CreateCustomer([Bind(Exclude = "Id")] Customer customer) 
{ 
    // model is invalid 
    if (!ModelState.IsValid) 
    { 
    return Json(new ActionInfo() 
    { 
     Success = false, 
     Message = "Validation failed" // you will probably want a more robust message :-) 
    }); 
    } 

    // service method accepts a Customer object rather than arbitrary strings 
    CustomerService.InsertCustomer(customer); 

    return Json(new ActionInfo() 
    { 
    Success = true, 
    Message = "Customer created successfully." 
    }); 

} 


如果您要報案意想不到的錯誤,如數據庫相關的異常,那麼你當然可以在對InsertCustomer的調用周圍添加try/catch塊,並返回將錯誤消息顯示回客戶端的必要結果。

+0

嘿thedude!非常感謝努力:)我完全同意你的綁定客戶實體(想做這樣的,不知道爲什麼,我已經把簡單參數的方法),以及異常處理是肯定的。有了xVal,我可以輕鬆地實現客戶端驗證,如果有人避開它,我會採取行動。但是,我將如何在這種情況下的字段旁邊顯示驗證消息? – 2009-10-15 08:54:34

+0

爲此,您希望從控制器操作中返回部分視圖而不是JSON。在你的部分視圖中,你可以使用Html.ValidationMessage()輔助方法來顯示每個字段的錯誤消息。由您的Data Annotations屬性生成的字段級別的錯誤消息可通過'ModelState'屬性提供給您的控制器。例如,要獲得名爲name的字段的第一個錯誤消息,您將通過「ModelState [」Name「] .Errors [0] .ErrorMessage'獲取它。另外,請看一下'Ajax.BeginForm'方法。過去,我用它取得了巨大的成功。 – 2009-10-15 15:18:45

+1

這就是我意識到,無論我將返回JSON或者部分觀點,那就是我不喜歡的事情......不過,我會看看如何對付它採用MS內置的Ajax特性,儘管我的願望是避免:)謝謝 – 2009-10-16 07:59:43

2

這是你提出問題後的一年多,但我已經在我的blog post中介紹了使用Ajax調用進行服務器端驗證,這可能對你很感興趣。我發現你將失敗的結果作爲成功的HTTP調用返回。我已經以不同方式處理這個(我想這是更正確的,因爲$.ajaxsuccesserror響應功能的能力)。你的特定例子是一個完美的例子,可以用我在博客文章中解釋的功能來實現。

基本上而不是總是返回成功響應(但有一告訴客戶端性質服務器端處理失敗)我共進退在服務器上的exeception並相應地處理它在客戶端上。我使用了一個自定義的ModelStateException類以及一個HandleModelStateException動作過濾器。