2011-03-05 130 views
0

我很努力地找到一種方法來處理我的視圖模型中的空值。其中一些值是我的模型中的嵌套或導航對象。如何在不將邏輯引入視圖的情況下讓我的視圖拋出空引用錯誤?這似乎很容易,但它是一天結束。NullReferenceException和視圖模型導航屬性

我有像這樣一些導航性能視圖模型:

ViewModel.cs

public class ViewModel 
{ 
    public ViewModel() {} 
    public ViewModel (Contact contact, IDemographicService demographicService) 
     : this() 
    { 
    Id = contact.Id; 
    Name = contact.Name; 
    EthnicityId = contact.EthnicityId; 
    if(EthnicityId > 0 || EthnicityId != null) 
     Ethnicity = deomographicService.GetEthnicityById((int)contact.EthnicityId); 
    } 
    public int Id {get;set;} 
    public string Name {get;set;} 
    public int? EthnicityId {get;set;} 
    public Ethnicity Ethnicity {get;set;} 
} 

我會跳過控制器,因爲那不是我的問題的重點。 (我知道邏輯可以進入控制器,但我選擇將其放入ViewModel中)。

MyView.cshtml

@model ViewModel 
<ul> 
<li>@Model.Name</li> 
<li>@Model.Ethnicity.Name</>//This is the null reference. 
</ul> 

我想我可以只定義「EthnicityName」字符串(如果返回null空),而不是整個對象,但有我需要從多個屬性實例種族對象。這消除了種族,無論是在視圖模型,控制器還是視圖中。總之,我該怎麼處理null.null?難住了。謝謝。

回答

1

我不認爲爲理解空值添加「邏輯」是一件可怕的事情。這種邏輯是底層.NET對象模型的一部分;這不是商業邏輯。

不過,你可以將一個屬性添加到模型爲您要在模型中可見的Ethnicity類型的每個屬性:

public Ethnicity Ethnicity {get;set;} 
public string EthnicityName { 
    get {return Ethnicity == null ? String.Empty : Ethnicity.Name;} 
    set {if (Ethnicity != null) {Ethnicity.Name = value;}} 
} 
public int EthnicityCode { 
    get {return Ethnicity == null ? 0 : Ethnicity.Code;} 
    set {if (Ethnicity != null) {Ethnicity.Code = value;}} 
} 

然後視圖沒有工作在所有做。

請注意,我認爲這種委派是好的,而不是格式。我永遠不會將屬性添加到僅用於格式設置的模型中。

+0

謝謝約翰。你的回答是我認爲我必須做的。雖然我的示例相當簡單,但我的項目包含其他具有大量屬性的「嵌套」對象,其中定義每個屬性都會影響視圖模型的目的。在這種類型的實例中,會創建一個空對象的「else」語句成爲verboten?即其他LargeObject = new LargeObject();這樣我的視圖有@ Model.LargeObject.Property不會拋出null。我討厭nulls,但我被迫與他們打交道。 – trevorc 2011-03-05 03:35:29

+0

p.s.我的意思是在視圖中使用邏輯 – trevorc 2011-03-05 03:50:21

+0

@name:我不是MVC專家,儘管我已經從關注點分離的角度得到了一般想法。我不認爲這是一個單獨的問題。我會問_why_的問題,我有那些空值 - 什麼是semanatics?他們代表什麼樣的模型? – 2011-03-07 18:24:29

1

這似乎是一個類設計問題,而不是視圖/模型問題。你有一個類聲明它將在初始化時提供一個種族作爲其不可變狀態的一部分。然而,當你實際創建這個對象時,你並沒有爲這個類的消費者做出保證。我認爲@John Saunders解決方案是可行的,但我更願意將Default種族實例作爲種族類型的靜態成員實例化並返回。該默認的名稱屬性將返回一個語言適當的答案「None Supplied」或類似的東西。

+0

Ritch我得到了你所說的,這是我考慮的事情,但是我的項目的實際情況(我的例子很簡單)是我有很大的對象圖表,不幸的是,它可以爲null。醫療保健索賠遇到撥款作家,並決定他的兄弟公共衛生試點項目更好看。 – trevorc 2011-03-05 03:48:36

+0

區分null和Empty是模型的行爲。 – 2011-03-05 03:55:31

+0

但基於我的例子種族不是空的它是空的。我無法控制用戶是否選擇了種族。因此,Ethnicity.Name == null.null。約翰的上述答案解決了這個問題,除非你有一個擁有很多屬性的大對象。 – trevorc 2011-03-05 04:24:45

0

您可能有興趣在ViewModel上實現IDataErrorInfo接口,因此在那裏實現驗證邏輯,而不是屬性getter/setters。