ASP.NET MVC操作返回不同的视图,或只是做了大量的操作?

Nat*_*ate 3 asp.net-mvc

所以,我处于这种情况,我需要根据经过身份验证的用户具有的"角色"显示不同的视图.

我想知道哪种方法最好:

[Authorize(Roles="Admin")]
public ActionResult AdminList(int? divID, int? subDivID) 
{
    var data = GetListItems(divID.Value, subDivID.Value);
    return View(data);
}

[Authorize(Roles = "Consultant")]
public ActionResult ConsultantList(int? divID, int? subDivID)
{
    var data = GetListItems(divID.Value, subDivID.Value);
    return View(data);
}            
Run Code Online (Sandbox Code Playgroud)

或者我应该做这样的事情

[Authorize]
public ActionResult List(int? divID, int? subDivID)
{
    var data = GetListItems(divID.Value, subDivID.Value);
    if(HttpContenxt.User.IsInRole("Admin")) 
    { return View("AdminList", data ); }

    if(HttpContenxt.User.IsInRole("Consultant")) 
    { return View("ConsultantList", data ); }

    return View("NotFound");
}
Run Code Online (Sandbox Code Playgroud)

tva*_*son 5

如果动作在概念上是相同的,但显示不同,我将有一个动作并根据你的鉴别器返回不同的视图.我会用你的第二个例子,稍加修改.请注意,如果用户不在适当的角色,则无需获取数据.

[Authorize] 
public ActionResult List(int? divID, int? subDivID) 
{ 
    var view = HttpContext.User.IsInRole("Admin")
                   ? "AdminList"
                   : (HttpContext.User.IsInRole("Consultant")
                         ? "ConsultantList"
                         : null);
    if (view == null)
    {
        return View("NotFound");
    }

    var data = GetListItems(divID.Value, subDivID.Value); 

    return View( view, data );
}
Run Code Online (Sandbox Code Playgroud)

当然,你意识到,当你引用一个潜在的null的值时,你有可能发生未处理的异常,对Nullable<int>吗?

此外,如果经常这样做,您可以将视图前缀的构造重构为常用方法.

public string GetRolePrefix()
{
    return HttpContext.User.IsInRole("Admin")
                   ? "Admin"
                   : (HttpContext.User.IsInRole("Consultant")
                         ? "Consultant"
                         : null);
}
Run Code Online (Sandbox Code Playgroud)

然后称之为

...
var prefix = GetRolePrefix();
if (prefix == null)
{
    return View("NotFound");  // more likely "NotAuthorized" ???
}

...get model...

return View( prefix + "List", data );
Run Code Online (Sandbox Code Playgroud)


ric*_*eym 5

我更喜欢第二种方法,但我认为你的控制器可以整理一下.根据我的喜好,那里有太多的逻辑,随着更多的角色被添加,它可能会增长.

一种方法是将丑陋的角色检查代码重构为服务层(如果您使用的是IoC容器,则可以注入):

[Authorize]
public ActionResult List(int? divID, int? subDivID)
{
    var permission = _userService.GetKeyRole(HttpContext.User);
    if(permission != null) 
    {
       var data = GetListItems(divID.Value, subDivID.Value);
       return View(permission + "List", data );
    }
    return View("NotFound");
}
Run Code Online (Sandbox Code Playgroud)

并提取的方法:

public class UserService : IUserService
{
    public string GetKeyRole(IPrincipal user)
    {
        if(user.IsInRole("Admin")) return "Admin";
        if(user.IsInRole("Consultant")) return "Consultant";
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)