2010-09-16 35 views
3

這是關於樣式和設計而不是語法的問題。MVC視圖中的過量空檢查

我有幾個(缺乏更好的術語)導航屬性的域模型。所以在我的強類型的詳細信息查看Foo其中有Bar類型的屬性我可以做到以下幾點:

<%: Foo.Bar.Name %> 

但是,有時候酒吧是空的,所以我最終的東西,如:

<%: Foo.Bar == null ? String.Empty : Foo.Bar.Name %> 

在其他情況下,因爲導航屬性I 的便利可能做更多的鏈接。但是,缺點是在View中引入了更多的空檢查。

作爲一種替代方案,我可以在ViewModel中執行所有的空檢查,以便將「乾淨」的東西傳遞給View。我正在尋找一些想法或常識指導原則,以避免在我的觀點中過度檢查空值。

P.S.我正在使用ASP.NET MVC,但我認爲這個問題可能與其他MVC框架有關。

回答

3

你已經自己回答了這個問題:

作爲替代方案,我可以做所有的空檢查在視圖模型讓我冒充是「乾淨」的視圖。

就是這樣,使用ViewModel。

+0

這是一個好的做法嗎?如果否則我的純粹的域模型就足夠了,這是否會是唯一的理由使用ViewModel? – Larsenal 2010-09-16 23:54:34

+0

@Larsenal雖然還有其他一些使用ViewModel的原因,但我使用ViewModel的一個很好的理由是讓代碼不受視圖影響。您發佈的場景恰好可以從中受益,但通過將代碼移動到視圖模型,您肯定會看到更多的場景,其中視圖的條件檢查可能更少。 – eglasius 2010-09-17 00:51:44

+0

使用它的另一個原因是因爲它非常有效,簡單地減少了允許發佈到控制器的內容。此外,你可以把asp.net的一些屬性放在那裏,否則它會讓你的原始模型。儘管如此,在非常小的項目中,我通常會在使用模型和查看模型之間進行切換,因爲有時模型只適合賬單。 – eglasius 2010-09-17 00:53:15

0

創建一個幫助程序,該幫助程序檢查null並返回適當的默認值。

例如,如果您有一個電話號碼字段,則將該字段和一個常數PHONE傳遞給它。助手檢查是否爲空,如果爲空,則顯示「無電話號碼可用」。

這樣你就可以在一個地方保留你所有的空檢查。

0

一個選項是使用助手,如here所述。

+0

該鏈接僅顯示如何檢查空字符串,答案甚至說..「當然,如果它的UserModified是空的,而不是用戶名,那麼你將需要一些不同的邏輯」 – 2010-09-16 20:44:17

0

您可以爲您的模型中的導航屬性提供延遲初始化。這樣你可以最小化遇到空值的風險。

public class Foo 
{ 
    private Bar _bar; 

    public Bar Bar 
    { 
     get 
     { 
      if (_bar == null) 
      { 
       _bar = new Bar(); 
      } 
      return _bar; 
     } 
    } 
} 

public class Bar 
{ 
    public string Name { get; set; } 
} 
+0

我當然可以做到這一點,但在一些例如,空值是正確的值。僅僅因爲我沒有加載屬性而遇到null是一個不同的問題。 – Larsenal 2010-09-16 21:39:55

+0

這就是爲什麼你應該使用空對象模式。將有效的空值作爲NullBar進行建模,然後添加邏輯來處理NullBar類中的空值。日誌等 – 2010-09-18 09:31:30

1

不知道是否真的有意義您的背景下,但是當你被過量空支票的困擾,你應該考慮的Null Object模式。

0

首先考慮在模型中,如果Bar爲空,Foo的實例是否有效。如果沒有,那麼你應該在構造函數和Bar屬性的setter中放置一個guard子句。

public class Foo{ 

     public BarClass _bar; 

     public BarClass Bar{ 
      get{return _bar; } 
      set{ 
       if(value == null) 
        throw new ArgumentNullException(); 
       _bar = value; } 
      } 

      public Foo(BarClass bar){ 
       if(bar == null) throw new ArgumentNullException(); 
       _bar = bar; 
      } 
     } 

其次,太多和重複的空檢查是代碼異味。您應該使用重構Replace Conditional with Polymorphism。您可以根據Null Object Pattern創建一個空對象。然後確保Bar屬性總是用NullBar初始化。

public class Foo{ 

    public BarClass _bar; 

    public BarClass Bar{ 
     get{return _bar ?? new NullBar(); } 
     set{ _bar = value ?? new NullBar(); } 
    } 

     public Foo(){ 
      Bar = new NullBar(); // initialization 
     } 
    } 

然後Bar永遠不會爲空。