2013-02-18 105 views
1

我對未從模型中的規則驗證的業務規則進行了驗證,但遇到了使其工作的問題。由於有兩種可能的情況(客戶或賣家註冊),因此需要在他們自己的觀點和模型中分別對待。賣家註冊從基本信息的客戶註冊繼承,所以客戶中的所有字段也都在賣家中。但是由於我正在使用兩種不同的模型,即使兩者的字段都與我正在進行驗證的字段相同,我也需要使用Object來使用相同的驗證方法。但不幸的是我很難這樣做。根據其類型鑄造對象

[CustomHandleError] 
private bool ValidateRegistrationForm (Object registerViewModelObject) { 
    if (registerViewModelObject is RegisterViewModel) 
    { 
     RegisterViewModel registerViewModel = 
      (RegisterViewModel)registerViewModelObject; 
    } 
    else 
    { 
     RegisterSellerViewModel registerViewModel = 
      (RegisterSellerViewModel)registerViewModelObject; 
    } 

    if (ModelState.IsValid) 
    { 
     string [] names = registerViewModel.Name.Split (
      new string [] {" "}, StringSplitOptions.RemoveEmptyEntries); 
     if (names.Length == 1) 
      ModelState.AddModelError ("Name", "Fill your full name"); 

     if (CustomerUtilities.IsCpf (registerViewModel.Identity) == false) 
      ModelState.AddModelError ("Identity", "Invalid CPF value"); 

     if (this.AuthenticatorService.IsExistentUser (registerViewModel.Email)) 
      ModelState.AddModelError ("Email", "Email already registered"); 
    } 
} 

正如你所看到的,if (ModelState.IsValid)後,智能感知不會在目前情況下找到registerViewModel。我想知道爲什麼會發生這種情況,因爲該變量是在if和else之間定義的,所以如果沒有定義它,就無法達到該代碼。

是否有任何解決方法(除了創建一個新的方法或傳遞2個變量)?

+2

將您的代碼作爲文本粘貼到此處,而不是圖像。 – 2013-02-18 20:12:19

+1

將代碼粘貼爲代碼塊可以讓您獲得更好的答案,因爲爲您生成正確的示例會更容易。 – driis 2013-02-18 20:14:47

+0

快速修復是將代碼複製並粘貼到if和else塊中。問題在於沒有用於註冊的公共基類,或者繼承沒有被正確使用(賣方註冊似乎不是一種客戶註冊,因此繼承會變得很難)。你必須做一些設計工作來解決這個問題。 – 2013-02-18 20:19:18

回答

1

如果您希望有兩個單獨的變量,那麼在if語句之外聲明並在之後測試null。

RegisterViewModel registerViewModel; 
RegisterSellerViewModel sellerModel; 

if (registerViewModelObject is RegisterViewModel) 
{ 
    registerViewModel = (RegisterViewModel)registerViewModelObject; 
} 
else 
{ 
    sellerViewModel = (RegisterSellerViewModel)registerViewModelObject; 
} 

但是,定義要使用的接口而不是Object將是更好的選擇。

public interface IRegisterViewModel 
{ 
    public string Name { get; set;} 
    public ... Identity {get; set;} 
    ... 
} 

public class RegisterViewModel : IRegisterViewModel 
{ 
    ... 
} 

public class RegisterSellerViewModel : IRegisterViewModel 
{ 
    ... 
} 

然後使用ValidateRegistrationForm(IRegisterViewModel registerViewModel),你可以擺脫if語句的全部。

+0

這種方法的問題是'if(ModelState.IsValid)'塊內的代碼重複。我正在尋找更整潔乾淨的東西。 TY的幫助,雖然 – leobelones 2013-02-18 20:25:47

+0

我加入了這樣做的界面方式,這可能是更多的你(和我)的喜好。 – 2013-02-18 20:32:40

2

在if範圍外聲明RegisterViewModel,並在if塊內分配它。

RegisterViewModel registerViewModel; 
if (registerViewModelObject is RegisterViewMOdel) 
{ 
    registerViewModel = // ... 
} 
else 
{ 
    registerViewModel = // ... 
} 
+0

感謝您的快速回答,但如果是這樣,我不會需要對象。問題是有兩種不同的模型,我在運行時選擇要定義的模型。 – leobelones 2013-02-18 20:16:16

+0

然後,您可能需要有一個公共基類或接口,以便您可以執行ModelState.IsValid if子句中的代碼。 – driis 2013-02-18 20:24:22

1

您應該從if statemtent之外定義RegisterViewModel。並在您的if聲明中進行分配。

贊;

RegisterViewModel registerViewModel; 
if(...) 
{ 
    //make your assigment here. 
} 
+0

正如我在其他答案中所述,我不知道使用哪種模型,因此我無法在if之外聲明它。 – leobelones 2013-02-18 20:17:55

0

你可能需要提取是常見的RegisterViewModelRegisterSellerViewModel到接口中的方法,並在這兩個類實現它。然後將registerViewModelObject轉換爲此接口,而不管其實際類型如何。

0

由於您沒有在函數的主要作用域中定義單個變量,因此會出現此問題。按照您編寫代碼的方式,您可以定義兩個位於不同作用域內的變量。

我將如何去解決方案:

我會做一個基類。

class RegisterModel 
{ 
    public string Name; 
    public IdentifyType Identify; 
    public string Email; 
} 

然後你的兩個類都可以繼承基類。像這樣:

class RegisterViewModel 
    : RegisterModel 
{...} 
class RegisterSellerViewModel 
    : RegisterModel 
{...} 

現在你實際上可以在函數中一次隱藏Object變量。像這樣:

private bool Validate(Object viewModel) 
{ 
    var castViewModel = (RegisterModel)viewModel; 
    if(ModelState.IsValid) 
    { 
     ... 
    } 
} 

請注意,如果viewModel不是RegisterModel類型,則會導致運行時錯誤。