its*_*att 6 asp.net asp.net-mvc roles asp.net-mvc-3
我@RenderSection("Contextual", false)在_Layout.cshtml中使用,允许不同的视图在那里呈现他们的特定内容.有些人没有,有些则没有.
此外,我使用基于角色的安全性和ActionFilter来控制特定用户是否可以访问特定的控制器操作,从而控制我的站点上的路由.
我想做的是提供一个@RenderSection("Contextual", false)关于我的_Layout.cshtml 的部分,然后让特定的页面提供对该页面有意义的任何上下文的东西,并让相应的控制器处理审查用户是否可以执行操作甚至可能看到选项存在,但我不确定我是否正确地考虑了这一点.以下是目前的情况:
现在我在我的一个Index.cshtml文件中有一个部分,如下所示:
@section Contextual {
<div>@Html.ActionLink("Create New", "Create")</div>
<div>@Html.ActionLink("Generate Report", "Report")</div>
<div>@Html.ActionLink("Other Stuff", "Other")</div>
}
Run Code Online (Sandbox Code Playgroud)
然后在我相应的控制器中,我有类似的东西:
[Authorize(Roles = "Editor")]
public ActionResult Create()
{
// stuff
}
Run Code Online (Sandbox Code Playgroud)
这将按我的意愿工作(非编辑器不会创建新项目),但Create条目可供所有人查看.我可以这样做:
@section Contextual {
@if (User.IsInRole("Editor"))
{
<div>@Html.ActionLink("Create New", "Create")</div>
}
<div>@Html.ActionLink("Generate Report", "Report")</div>
<div>@Html.ActionLink("Other Stuff", "Other")</div>
}
Run Code Online (Sandbox Code Playgroud)
这样做效果很好,隐藏了非编辑的创建链接,但是我已经开始关注这样做是否好处,而且我可以看到在路上我遇到的情况规则改变然后我有两个位置保持同步:控制器动作的属性和视图中的代码.
这是一种合理的方法吗?有没有更好的方法来解决这个问题?
我喜欢使用对于在控制器上填充的视图模型更明确的标志.
例如:
// on the controller
viewModel.CanCrete = User.IsInRole("Editor");
// ...snip...
return View(viewModel);
}
Run Code Online (Sandbox Code Playgroud)
因此,您需要将此标志添加到视图模型中,或者可能添加到视图模型的基类中.您可以创建自定义操作筛选器以在多个控制器中填充它或在控制器基类中执行某些操作.
我还想定义一个方便的扩展方法:
public static string If( this string s, bool condition )
{
return condition ? s : String.Empty;
}
Run Code Online (Sandbox Code Playgroud)
根据您使用的API,您可能还需要扩展MvcHtmlString.
然后在视图中:
@section Contextual {
<div>@Html.ActionLink("Create New", "Create").If(Model.CanCrete)</div>
<div>@Html.ActionLink("Generate Report", "Report")</div>
<div>@Html.ActionLink("Other Stuff", "Other")</div>
}
Run Code Online (Sandbox Code Playgroud)
你可以决定你想做什么div,你可能想要另一个帮助包裹div中的链接,或者你可以使用CSS来实现你想要的任何视觉布局.