2013-03-20 44 views
3

我被要求避免添加类似if/else视图内部的逻辑。目前,我正在开发页面的登录/注册功能,并且我必须显示一组链接if如果用户在另一个角色中,则用户处于角色而另一个角色。避免在视图内添加if/else逻辑

这是我迄今所做的:

<ul id="menu"> 
    <li>@Html.ActionLink("Products", "Books", "Home")</li> 
    @if (User.Identity.IsAuthenticated) 
    { 
     <li>@Html.ActionLink("Log Out" ,"LogOut","Account")</li> 
    } 
    else 
    { 
     <li>@Html.ActionLink("Log In" ,"LogIn","Account")</li> 
    } 
    @if(User.IsInRole("administrator")) 
    { 
     <li>@Html.ActionLink("Product Manager", "Books", "ProductManager")</li> 
    } 
</ul> 

此代码存储在_Layout.cshtml file.I里面想避免添加逻辑到视图中。

有什么办法可以做到吗?

+0

为什么逻辑是这样的观点是一件坏事? – Dutts 2013-03-20 07:36:25

+1

mvc的漏洞点是分离逻辑,标记和数据,所以我认为这是一种不好的做事做法 – aleczandru 2013-03-20 07:37:57

+0

我不认为这必然是非mvc,这个逻辑只涉及到视图。 – Dutts 2013-03-20 07:39:17

回答

6

如果你不想在视图中这样做,我想你会在控制器中做到这一点。像这样的东西会从个人的观点删除条件语句工作:

// controller 
ActionResult MyAction() 
{ 
    if (!User.Identity.IsAuthenticated) 
    { 
     ViewBag.MenuControl = "Menu/NotLoggedIn" 
    } 
    else if (User.IsInRole("Administrator")) 
    { 
     ViewBag.MenuControl = "Menu/Administrator" 
    } 
    else 
    { 
     ViewBag.MenuControl = "Menu/LoggedIn" 
    } 

    ... 
} 

// view 
@Html.Partial(ViewBag.MenuControl); 

还是要跨越很多意见分享这个逻辑,我建议你对住房创建一个特定的MenuController这个逻辑。

ActionResult RenderMenu() 
{ 
    string template; 
    if (!User.Identity.IsAuthenticated) 
    { 
     template = "Menu/NotLoggedIn" 
    } 
    else if (User.IsInRole("Administrator")) 
    { 
     template = "Menu/Administrator" 
    } 
    else 
    { 
     template = "Menu/LoggedIn" 
    } 

    return View(template); 
} 

// view 
@Html.Action("RenderMenu", "MenuController") 

然而 ...有“视图逻辑”和“控制器逻辑”之间大的差异。毕竟,这是我们希望在MVC体系结构中将控制视图与控制器分开的主要原因之一。像“避免视图中的所有条件语句”这样的简单规则确实错过了MVC的设计方式。

我真的更喜欢在视图中这样做,因为实际上它与如何格式化视图有关,而不是控制器应该如何运行。我会坚持你现在的代码。

5

我认为在您的视图中有if/else声明没有任何问题。问题在于实际的条件语句本身。

借此例如:

@if(User.IsInRole("administrator")) 
{ 
    <li>@Html.ActionLink("Product Manager", "Books", "ProductManager")</li> 
} 

在这里,您与视图逻辑混合业务逻辑。您正在引用角色的名称。这与观点无关。为了解决这个问题,试试这个:

型号代码

public class MyModel 
{ 
    public bool IsAdministrator { get; } 
} 

控制器代码

myModel.IsAdministrator = User.IsInRole("administrator"); 

查看代码

@if(this.Model.IsAdministrator) 
{ 
    <li>@Html.ActionLink("Product Manager", "Books", "ProductManager")</li> 
} 
+0

+1指出* IsAdministrator *测试应该在模型中。 – 2013-03-20 08:09:19

1

MVC的漏洞点是分离责任区域。该模型必须是完全独立的,也就是只知道自己。在模型中使用与表示相关的逻辑是非常正常的,除非将其与业务逻辑混合。在您的示例中,显而易见的改进可能是将所有授权信息移动到模型对象中,并保留if/else逻辑。

控制器:

model.IsAuthenticated = User.Identity.IsAuthenticated; 
model.IsAdministrator = User.IsInRole("administrator");