【问题标题】:Improve separation of view and logic改进视图和逻辑的分离
【发布时间】:2012-02-26 19:40:20
【问题描述】:

我正在设计一些网络应用程序,我选择了一些 _layout.cshtml,其中的片段:

//some html
<h4>Your account</h4>
@{ Html.RenderPartial("UserMenu"); }

负责渲染菜单视图。它有 3 种可能的状态 - 以管理员身份登录、以用户身份登录、未登录。我做了这样的局部视图:

@if (User.IsInRole("Admin"))
{
    @:Admin menu
}
else
{
    if (User.Identity.IsAuthenticated)
    {
        @:Normal menu
    }

    else
    {
        @Html.ActionLink("Login", "Logon", "Account");
    }
}

但我对这个解决方案并不满意,因为它的逻辑和视图分离度很差。你建议如何改进它?

【问题讨论】:

    标签: c# asp.net-mvc asp.net-mvc-3 razor partial-views


    【解决方案1】:

    但我对这个解决方案并不满意,因为它的逻辑和视图分离度很差

    我不同意。对我来说,这种逻辑在视图中是完全可以接受的。你可以编写一个自定义的 HTML 帮助器,它可以像这样在你的布局中使用:

    <h4>Your account</h4>
    @Html.Menu()
    

    并将逻辑放在帮助程序中,而不是使用这个部分。如果你决定实现它,它的外观如下:

    public static class HtmlExtensions
    {
        public static IHtmlString Menu(this HtmlHelper htmlHelper)
        {
            var user = htmlHelper.ViewContext.HttpContext.User;
            if (user.IsInRole("Admin"))
            {
                return new HtmlString("Admin menu");
            }
    
            if (user.Identity.IsAuthenticated)
            {
                return new HtmlString("Normal menu");
            }
    
            return htmlHelper.ActionLink("Login", "Logon", "Account");
        }
    }
    

    【讨论】:

    • 当然不是,但我个人不喜欢 if-else(if-else) 之类的结构,因为我认为这是对不应该承担的职责负责。我宁愿考虑一些助手,它会从可能的 3 中选择适当的 PartialView - 你怎么看?
    【解决方案2】:

    如果您在服务器端进行验证和授权检查,我认为没有任何重大问题。

    你有的“逻辑”不是业务逻辑,所以有if语句是可以接受的。

    【讨论】:

      【解决方案3】:

      另一种可能是这样的:

      定义一个基类或接口,比如“UserState”。定义三个扩展该类的类,每个类代表用户的不同状态,如 UserAdmin、UserNormal、UserAnonymous。

      在模型逻辑中定义一个方法,如下所示: <pre></pre>

      public void UserState GetUserState(User user)
      {
          if (user.IsInRole("Admin"))
          {
              return new UserAdmin(user);
          }
          if (user.Identity.IsAuthenticated)
          {
              return new UserNormal(user);
          }
          return new UserAnonymous();
      }
      

      您也许可以从 html 帮助程序中调用它:

      
      
      
      public static UserState GetUserState(this HtmlHelper html)
      {
          var user = html.ViewContext.HttpContext.User;
          return MyModelLogic.GetUserState(user);
      }
      

      然后,在_layout.cshtml中:

      
      
      
      @{ var userState = Html.GetUserState(); }
      @Html.DisplayFor(_ => userState)
      

      最后,您可以为每个继承 UserState 的类实现一个单独的显示模板。这样一来,您对于用户的每个状态都有一个单独的视图,而决定使用哪个状态的逻辑与表示层无关。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-15
        • 2022-10-03
        • 1970-01-01
        • 1970-01-01
        • 2012-09-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多