避免向剃刀视图引擎显示Null或特定值

时间:2013-08-14 23:36:13

标签: asp.net-mvc asp.net-mvc-3

我正在使用MS Sql server 2008 express rc2处理asp.net mvc3 Web应用程序。在我的应用程序中,我在DB中有两个不同的品牌,其中一个很少有空或者未知的'值(例如' unknown'被添加到DB而不是Null)。我的问题是如何只将非空值传递给View Engine而不是在View中使用If / Else语句?

控制器中的

var model = _data.GetViewModel(query);
        if (model != null)
        {                
            return View(model);
        }
        else
            return View("Error");

在ViewModel中;

    public int Id { get; set; }
    public string Query { get; set; }
    public string Brand { get; set; }
    public string Family { get; set; }
    public string Type { get; set; }
模型中的

    public ViewModel GetViewModel(string query)
    {
        var data = _comp.Get(p => p.Query == query);
        if (data == null) return null;
        return new ViewModel
        {
            Id = data.id,
            Brand = data.brand,
            Family = data.family,
            Type = data.type
        };
   }
在视图中

(我目前正在使用If语句):

@if (Model.Brand != null)
{
<span class="brand">@Model.Brand</span> 
}

@if (Model.Family != null)
{
<span class="family">@Model.Family</span> 
}

@if (Model.Type != null)
{
<span class="type">@Model.Type</span>
}

注意:我想避免使用If语句,因为每个品牌的数据库中有太多的值,而且其中很多都是Null,所以我不想为那些Null值生成Html。我正在使用像上面的代码一样的If / Else语句,并且使用If检查View中的太多值,它会占用服务器和处理器上的内存,并且还会减慢服务器响应时间。

我想有另一种方法来做到这一点。我应该使用部分观点还是其他什么? 请帮我解决这个问题,非常感谢你的帮助。 感谢致敬。

2 个答案:

答案 0 :(得分:3)

首先,一些背景/背景,然后是我的建议。

(顺便说一下,这一切都适用于ASP.NET MVCASP.NET NancyFX的任何版本(是的,还有其他选项!!)等等)

背景/背景。

要解决这个问题,人们通常会分为两类:

  1. 只需获取数据并让View决定要显示的内容(常见的一种,而不是IMO的正确方式)。
  2. Controller应处理所有繁重的工作,并为视图提供完全答案(正确的方式,IMO)。
  3. 第一种方式快速而肮脏。当然它有效,但它给视图带来了太多的逻辑。 Views根本不应该做任何逻辑(例外:for循环,可能奇怪的if / else ..也许......)。主要原因是 TESTING 。是的,人们讨厌的那个肮脏的词,并认为它只适用于嬉皮士。或者.. 我没时间测试..所以我手动测试等。如果你把 ANY 业务逻辑放到视图中,你就无法测试

    第二种方式起初可能看起来有点慢,但这就像任何东西 - 你的实践越多,你去的速度就越快。这是(IMO)首选的方法,因为你可以测试控制器:)控制器应该创建一个视图模型,它将具有视图所需的精确结果。不是额外的。例如,假设您想要将Brands列表返回到显示/视图。大多数人(相当于)Get-all-brands进入一个列表..并将该列表发送到视图中......即使80%的这些属性都不会被该视图使用!即使该视图不会使用ONE属性..也不要检索它,也不要将它发送到视图中!

    所以 - TL; DR;完成控制器中的所有繁重工作。观点是愚蠢的。只需将精确的视图模型数据转储到视图中。

    解决您的问题

    好的,让我们滚动想法#2并在控制器中发生所有这些事情。

    // Grab the results.
    // ASSUMPTION: It is only returning the -exact- data I need. No more, no less.
    var results = _data.GetViewModel(query);
    if (model == null)
    {                
    
    // Project the results into a perfectly tight & svelte view model 
    // 100% specific for this view.
    var viewModel = results.
                    Select(x => new ViewModel
                    {
                        Id = x.Id,
                        Brand = string.IsNullOrEmpty(x.Brand) 
                                  ? string.Empty 
                                  : x.Brand,
                        Family = string.IsNullOrEmpty(x.Family) 
                                  ? string.Empty 
                                  : x.Family,
                        Type = string.IsNullOrEmpty(x.Type) 
                                  ? string.Empty 
                                  : x.Type,
                    }).ToList();    
    
    
    return viewModel;
    

    测试此..

    [Fact]
    public void GivenSomeBrands_Index_ReturnsAViewModel()
    {
        // Arrange.
        // NOTE: Our fake repostitory has some fake data. In it ..
        //       Id: 1, Brand: Gucci.
        //       Id: 22, Brand: null.
        var controller = new BrandController(SomeFakeRepositoryThingy);
    
        // Act.
        var result = controller.Index(); // This calls that controller code, above.
    
        // Assert.
        Assert.IsNotNull(result); // Controller returned some result.
        Assert.IsNotNull(result.Model); // We have some model data.
    
        var model = result.Model as IList<ViewModel>(); // Cast the Model value.
        Assert.NotNull(model); // We have a strongly typed view model.
    
        // We check the first brand value.
        Assert.Equal("Gucci", model.First().Brand); 
    
        // We know this item has a null Brand, 
        Assert.Equal(string.Empty, model[21].Brand); but the ViewModel converted it.
    }
    

答案 1 :(得分:0)

您可以编写自定义HTML帮助程序:

public static string MyHelper<V>(this HtmlHelper helper, V value, string css)
{
    if (value == null)
        return "";

    return String.Format("<span class='{0}'>{1}</span>", value, css);
}

然后在你看来:

@Html.MyHelper(Model.Brand, "brand");
@Html.MyHelper(Model.Family, "family");
@Html.MyHelper(Model.Type, "type");