改善视图和逻辑的分离

时间:2012-02-26 19:40:21

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

我正在设计一些网络应用程序,我去了一些_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");
    }
}

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

3 个答案:

答案 0 :(得分:2)

  

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

我不同意。对我来说,这种逻辑在视图中是完全可以接受的。你可以编写一个自定义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");
    }
}

答案 1 :(得分:0)

我没有看到任何重大问题,如果你有验证和&amp;授权检查服务器端。

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

答案 2 :(得分:0)

另一种可能性是:

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

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

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 void UserState GetUserState(User user)
{
    if (user.IsInRole("Admin"))
    {
        return new UserAdmin(user);
    }
    if (user.Identity.IsAuthenticated)
    {
        return new UserNormal(user);
    }
    return new UserAnonymous();
}

然后,在_layout.cshtml中:

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

最后,您可以为继承UserState的每个类实现单独的显示模板。这样,您就可以为用户的每个状态设置单独的视图,并且决定使用哪个状态的逻辑与表示层无关。