NullReferenceException 和视图模型导航属性

发布于 2024-10-20 13:19:12 字数 1096 浏览 1 评论 0原文

我正在努力寻找一种方法来处理视图模型中的空值。其中一些值是我的模型中的嵌套对象或导航对象。如何在不向视图中引入逻辑的情况下防止视图抛出空引用错误?这看起来很容易,但今天已经结束了。

我有一个带有一些导航属性的视图模型,如下所示:

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)而不是整个对象,但在某些情况下,我需要 Ethnicity 对象中的多个属性。这消除了种族,无论是在视图模型、控制器还是视图中。简而言之,对于 null.null 我该怎么办?难住了。谢谢。

I am struggling to find a way to deal with null values in my view model. Some of these values are nested or navigation objects within my model. How do I keep my view from throwing a null reference error without introducing logic into the view? This seems easy but it is the end of the day.

I have a view model with some navigation properties like so:

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;}
}

I'll skip the controller because that is not the focus of my question. (I know that the logic can go in the controller but I chose to put it in the ViewModel).

MyView.cshtml

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

I guess I could define only a "EthnicityName" string (and if null return null) instead of an entire object but there are instances where I need more than one property from the Ethnicity object. This eliminates Ethnicity, whether it is in the view model, controller, or view. In short, what do I do about null.null? Stumped. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

幽梦紫曦~ 2024-10-27 13:19:12

我不认为添加“逻辑”来理解空值是一件可怕的事情。此类逻辑是底层 .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;}}
}

这样视图就无需执行任何操作。

请注意,我认为这种委托是可以的,而不是格式化。我永远不会向模型添加仅用于格式化目的的属性。

I hardly think it's a terrible thing to add "logic" for understanding null values. Such logic is part of the underlying .NET object model; it's not business logic.

Still, you can add one property to the model for each property of the Ethnicity type that you want visible in the model:

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;}}
}

Then the view has no work to do at all.

Note that I think that this sort of delegation is ok, as opposed to formatting. I would never add a property to the model that was only for the purpose of formatting.

时光是把杀猪刀 2024-10-27 13:19:12

这看起来像是一个类设计问题,而不是一个视图/模型问题。您有一个类,声明它将在初始化时提供种族作为其不可变状态的一部分。然而,当您实际创建对象时,您并没有为该类的使用者做出这种保证。我认为 @John Saunders 解决方案是可行的,但我更愿意将默认种族实例实例化为种族类型的静态成员并返回它。该默认值的 Name 属性将返回“未提供”或类似内容的适合语言的答案。

It seems like a class design problem, not a View/Model problem. You have a class that declares that it will provide an Ethnicity as part of its immutable state upon initialization. However, when you actually create the object you aren't making that guarantee for the class's consumers. I think that @John Saunders solution is viable, but I would be more willing to instantiate a Default Ethnicity instance as a static member on the Ethnicity type and return that. The Name property of that default would return a language appropriate answer for "None Supplied" or something like that.

秋凉 2024-10-27 13:19:12

您可能有兴趣在 ViewModel 上实现 IDataErrorInfo 接口,因此在那里实现验证逻辑,而不是在属性 getter/setter 上实现。

You might be interested in implementing the IDataErrorInfo interface on your ViewModel therefore implementing validation logic there instead of right on the properties getter/setters.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文