将复杂的条件语句移动到代码隐藏

本文关键字:代码 隐藏 移动 语句 复杂 条件 | 更新日期: 2023-09-27 17:47:21

我只是想知道,通过将复杂的 if else 语句和生成的 html 标记移动到后面的代码是否违反了某些"MVC"定律?

当面对内联 if else 语句时,这似乎是一个很好的选择,这些语句可能会变得非常不可读。

将复杂的条件语句移动到代码隐藏

在您看来,有条件并不可怕。 我会将它们保留在 ASPX 中,而不是后面的代码中。 但是,条件通常表示控制行为。 请考虑以下 ASPX 代码:

<%if (ViewData["something"] == "foo") {%>
     <%=Html.ActionLink("Save", "Save") %> 
<%}%>
<%if (ViewData["somethingElse"] == "bar") {%>
     <%=Html.ActionLink("Delete", "Delete") %> 
<%}%>

这组条件表示视图正在处理的控制行为 - 即在错误的位置。 此行为不可进行单元测试。 相反,请考虑:

<%foreach (var command in (IList<ICommand>)ViewData["commands"]) {%>
     <%=Html.ActionLink(command) %>
<%}%>

在此示例中,ActionLink 是 HtmlHelper 的自定义扩展,它采用我们自己的 ICommand 规范对象。 呈现此视图的控制器操作根据各种条件填充 ViewData["命令"]。 换句话说,控制器进行控制。 在此操作的单元测试中,我们可以测试在各种条件下是否会显示正确的命令集。

起初,与快速将几个 IF 扔进视图中相比,这似乎很麻烦。 你必须问自己的问题是,"这个IF是否代表控制行为,我是否想确保在某个时候不会中断?

我不想在我的视图中使用类背后的代码。这不是因为它默认违反了 MVC,而是因为我发现"自然"方式(至少对我来说)是不同的。

当我遇到与纯粹视图问题相关的复杂 HTML 标记时,我通常会为类编写一个扩展方法HtmlHelper以隐藏复杂性。因此,我有像 Html.MoneyTextBox()Html.OptionGroup()Html.Pager<T> 这样的扩展。

在其他情况下,当出现复杂条件时,通常我错过了控制器的某些内容。例如,与元素的可见性、只读或启用相关的所有问题通常都源于控制器可以提供的内容。在这种情况下,我不是将模型传递给视图,而是创建一个视图模型,该模型封装了模型和控制器可以提供的其他信息,以简化 HTML 标记。视图模型的典型示例如下:

public class CustomerInfo
{
  public Customer Customer { get; set; }
  public bool IsEditable { get; set; }  // e.g. based on current user/role
  public bool NeedFullAddress { get; set; }  // e.g. based on requested action 
  public bool IsEligibleForSomething { get; set; }  // e.g. based on business rule
} 

也就是说,背后的代码是视图的一部分,因此您可以自由使用它,如果它更适合您的需求。

我相信只要

它是一个渲染代码并且它在"视图"而不是在控制器中,那么将其放在后面或内联的代码上就无关紧要了。只要确保不要在控制器操作中编写这段渲染代码(这样你就会真正违反 MVC 模式)。

代码隐藏是视图的一部分 - 如果要直接在 ASPX 中或代码隐藏中放置内容,则由您决定。MVC并不意味着你必须在ASPX:)中编写所有丑陋的东西。