MVC 视图中过多的 Null 检查

发布于 2024-09-19 06:27:15 字数 528 浏览 6 评论 0原文

这是一个关于风格和设计而不是语法的问题。

我的域模型具有多个(由于缺乏更好的术语)导航属性。因此,在具有 Bar 类型属性的 Foo 强类型详细信息视图中,我可以执行以下操作:

<%: Foo.Bar.Name %>

但是,有时 Bar 为 Null,所以我最终会得到类似的结果:

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

在其他情况下,因为导航属性的便利性,我可以做更多的链接。然而,缺点是在我的视图中引入了更多的空检查。

作为替代方案,我可以在 ViewModel 中执行所有空检查,以便将一些“干净”的内容传递给视图。我正在寻找一些想法或常识指南,以避免在我的观点中进行过多的空检查。

PS 我正在使用 ASP.NET MVC,但我认为这个问题可能与其他 MVC 框架相关。

This is a question about style and design rather than syntax.

I have domain models that have several (for lack of a better term) navigation properties. So in my strongly typed details view of Foo which has a property of type Bar I could do the following:

<%: Foo.Bar.Name %>

However, sometimes Bar is Null, so I end up with something like:

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

In other cases, because the convenience of the navigation properties I could do even more chaining. The downside, however, is the introduction of more null checking in my View.

As an alternative, I could do all the null checking in a ViewModel so that I've passed off something "clean" to the View. I'm looking for some ideas or common sense guidelines for avoiding excessive null checking in my views.

P.S. I'm using ASP.NET MVC, but I think this question may be relevant to other MVC frameworks.

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

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

发布评论

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

评论(6

┈┾☆殇 2024-09-26 06:27:15

你自己已经回答了:

作为替代方案,我可以在 ViewModel 中执行所有 null 检查,以便将一些“干净”的内容传递给 View。

就是这样,使用 ViewModel。

You already answered it yourself:

As an alternative, I could do all the null checking in a ViewModel so that I've passed off something "clean" to the View.

That's it, use a ViewModel.

焚却相思 2024-09-26 06:27:15

不确定它在您的上下文中是否真的有意义,但是当您被过多的空检查困扰时,您应该考虑 空对象 模式。

Not sure whether it really makes sense in your context, but when you are bothered by an excess of null-checks, you should contemplate the Null Object pattern.

五里雾 2024-09-26 06:27:15

创建一个帮助器来检查 null 并返回适当的默认值。

例如,如果您有一个电话号码字段,则可以向其传递该字段和一个常量 PHONE。帮助器检查是否为空,如果为空则显示“没有可用的电话号码”。

这样您就可以将所有空检查保留在一个地方。

Create a helper that checks for null and returns an appropriate default.

For example if you have a phone number field, you pass it the field and a constant PHONE. the helper checks if null and displays "No phone number Available" if it is null.

This way you keep all your null checking in one place.

心房的律动 2024-09-26 06:27:15

一种选择是使用助手,如此处所述。

One option is using a helper, as described here.

何必那么矫情 2024-09-26 06:27:15

您可以为模型中的导航属性提供延迟初始化。这样您就可以最大限度地减少遇到空值的风险。

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

You could provide lazy initialization for your navigation properties in you model. That way you could minimize the risk of encountering null values.

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; }
}
稀香 2024-09-26 06:27:15

首先考虑在您的模型中,如果 Bar 为 null,则 Foo 的实例是否有效。如果不是,那么您应该在 Bar 属性的构造函数和/或设置器中放置一个保护子句。

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

其次,过多且重复的空检查会产生代码异味。您应该使用重构用多态性替换条件。您可以根据空对象模式创建空对象。然后确保 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 永远不会为空。

First consider whether in your model an instance of Foo is valid if Bar is null. If no then you should put a guard clause in the constructor and\or the setter of the Bar property.

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

Secondly, too many and duplicated null checks is a code smell. You should use the refactoring Replace Conditional with Polymorphism. You can create a Null object according to the Null Object Pattern. Then make sure that the Bar property is always initialized with 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
       } 
    }

Then Bar will never be null.

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