2010-05-25 43 views
1

我有一個相當複雜的模型需要驗證,問題在於這個模型在兩個不同的地方使用,一個是註冊客戶,另一個是簡單地添加地址。地址上的某些字段在註冊客戶表單上根本不可見。 因此,當我檢查是否ModelState.IsValid我當然因爲例如得到錯誤。該姓名不是輸入在帳單地址上,而是在客戶身上。這就是爲什麼我想在驗證發生之前,將幾個字段複製到模型,然後驗證。我有點失落,但我需要幫助。在驗證之前需要複製屬性

我的行動看起來是這樣的:

public ActionResult Register(WebCustomer customer) 
{ 
    customer.CopyProperties(); 
    if(TryUpdateModel(customer)) 
    { 
     ... 
    } 
    ... 

但它始終返回false,並ModelState.IsValid仍然是假的。

+1

farily =相當還是真實? – 2015-11-26 13:41:00

回答

3

我認爲,在這種情況下,最好的辦法,就是寫CustomModelBinder,並將其應用到你的動作參數

public ActionResult Register([ModelBinder(typeof(WebCustomerRegisterBinder))]WebCustomer customer) 
{ 
    if(TryUpdateModel(customer)) 
    { 
    ... 
    } 
    ... 
} 

這CustomModelBinder應採取複製領域的護理,而且由於其應用到動作參數它將僅用於此操作。

+0

但我將如何檢索從表單發佈的所有值呢? – 2010-05-25 08:18:08

+0

TryUpdateModel()將嘗試將表單中的值放入您的客戶對象中(唯一可能出錯的是TryUpdateModel將缺少的字段設置爲null並且導致模型驗證失敗),只需嘗試一下。 – tpeczek 2010-05-25 08:41:27

+0

這就是發生了什麼呀,因爲所有CopyProperties所做的就是使用像Name這樣的屬性並將其複製到Name的Addresses屬性中,並且如果Name爲null,則可以找出其餘的:) – 2010-05-25 09:00:26

1

Binder正在處理表單值。所以,你的ModelState總是會拋出一個錯誤。你必須檢查你的實體中的屬性,或者第二個選項寫你自己的模型綁定器。例如。

public class Customer 
{ 
    public bool IsValid() 
    { 
     //TODO: check properties. 
    } 
} 

public ActionResult Register(WebCustomer customer) 
{ 
    customer.CopyProperties(); 
    TryUpdateModel(customer); 
    if (customer.IsValid()) 
    { 
     ... 
    } 
    ... 
1

我解決了這一點diffferently,不知道這是否是最好的方法,但是:

首先,我對ModelStateDictionary

public static void ResetErrors(this ModelStateDictionary modelState) 
{ 
    foreach (var error in modelState.Values.Select(m => m.Errors)) 
{ 
    error.Clear(); 
} 
} 

然後做一個擴展方法,我沒有在下面我的動作:

ModelState.ResetErrors(); 
customer.CopyProperties(); 
ValidateModel(customer);