我正在使用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中的太多值,它会占用服务器和处理器上的内存,并且还会减慢服务器响应时间。
我想有另一种方法来做到这一点。我应该使用部分观点还是其他什么? 请帮我解决这个问题,非常感谢你的帮助。 感谢致敬。
答案 0 :(得分:3)
首先,一些背景/背景,然后是我的建议。
(顺便说一下,这一切都适用于ASP.NET MVC
或ASP.NET NancyFX
的任何版本(是的,还有其他选项!!)等等)
要解决这个问题,人们通常会分为两类:
Controller
应处理所有繁重的工作,并为视图提供完全答案(正确的方式,IMO)。第一种方式快速而肮脏。当然它有效,但它给视图带来了太多的逻辑。 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");