2

我有一個訂單輸入頁和對應的視圖模型(簡化的示例):爲Ajax POST請求驗證數據

public class OrderCreateViewModel 
{ 
    [Required] 
    [StringLength(100)] 
    public string Remark { get; set; } 

    [Required] 
    [StringLength(50)] 
    public string AddressCity { get; set; } 
} 

該模型被用於創建視圖:

@model MyNamespace.OrderCreateViewModel 

@using (Html.BeginForm()) 
{ 
    @Html.ValidationSummary(false) 
    @Html.EditorFor(model => model.Remark) 
    @Html.EditorFor(model => model.AddressCity) 
    <input type="submit" value="Create order" name="saveButton" /> 
} 

create操作對於控制器中的POST請求是:

[HttpPost] 
public ActionResult Create(OrderCreateViewModel viewModel) 
{ 
    if (ModelState.IsValid) 
    { 
     // Save order in DB 
     return RedirectToAction("Index");    
    } 
    return View(viewModel); 
} 

命令(必填字段和字符串的長度)得到驗證d在客戶端(使用不顯眼的Javascript,jQuery驗證)和服務器端(ModelState.IsValid)。

現在,我在頁面中添加第二個按鈕,其目的是在主表中保存AddressAddressCity)。這應該有一個Ajax POST請求(使用jQuery)發生:

<input id="buttonAddAddress" type="button" value="Add address" /> 

Click事件處理程序掛到該按鈕,讀取相關的地址(僅在例如AddressCity)輸入字段的內容和發送POST請求到服務器:

$("#buttonAddAddress").click(function() { 
    var address = JSON.stringify({ 
     City: $('#AddressCity').val() 
    }); 

    $.ajax({ 
     type: 'POST', 
     url: '@Url.Action("AddAddress")', 
     data: address, 
     dataType: 'json', 
     contentType: 'application/json; charset=utf-8', 
     ... 
    }); 
}); 

該控制器具有用於此請求對應的POST操作:

[HttpPost] 
public ActionResult AddAddress(Address address) 
{ 
    // Create address in database 
    return Json(true); 
} 

Address是一個輔助類型:

public class Address 
{ 
    public string City { get; set; } 
    // ... 
} 

此代碼不驗證AddressCity是必需的,必須不超過50個字符。

問題:如何爲此Ajax POST請求添加驗證 - 客戶端和服務器端驗證?我不知道如何在客戶端做到這一點。在服務器端,我想避免顯而易見的重要解決方案來重複驗證屬性的含義(如if (!string.IsNullOrEmpty(address.City) && address.City.Length <= 50) ...等),並利用現有的驗證屬性(如果可能的話)。

+1

我有一個類似的問題,我不得不通過ajax調用處理驗證錯誤,我跟着http:// err aticdev.blogspot.com/2010/11/handling-validation-errors-on-ajax.html,但這與返回partialviews vs json結果更相關。 –

回答

3

對於服務器:

public class Address 
{ 
    [Required] 
    [StringLength(50)] 
    public string City { get; set; } 
} 

,併爲客戶,因爲你使用的是AddressCity領域,它已經具有相同的驗證規則從主視圖模型應用的一個。

但因爲我猜你會告訴我,這是不幹燥,那麼,OOP救援:

public class AddressViewModel 
{ 
    [Required] 
    [StringLength(50)] 
    public string City { get; set; } 
} 

和你的主視圖模型:

public class OrderCreateViewModel: AddressViewModel 
{ 
    [Required] 
    [StringLength(100)] 
    public string Remark { get; set; } 
} 

和你們各自的控制器動作:

[HttpPost] 
public ActionResult Create(OrderCreateViewModel viewModel) 
{ 
    ... 
} 

[HttpPost] 
public ActionResult AddAddress(AddressViewModel address) 
{ 
    ... 
} 
+0

@Slauma,yeap,然後簡單地'if(ModelState.IsValid)'。 –

+0

這看起來很簡單!如果'AddressViewModel'是'OrderCreateViewModel'的成員而不是繼承,它也可以工作嗎? – Slauma

+0

@Slauma,是的,它會工作。 –