ASP.NET MVC - 可选择从基础 Class 方法重定向?
ASP.NET MVC - Optionally Redirect from a Base Class Method?
考虑以下在我的许多控制器操作中重复出现的代码块。 (我主要关注方法体的前 6 行)。
[HttpGet]
public ActionResult OptOut()
{
var user = this.SecurityPrincipal;
if (user.IsReadOnlyUser)
{
this.TempData["ViewModel"] = new AuthorizationModel { User = user };
return this.RedirectToAction("NotAuthorized", "Authorization");
}
var model = /* Elided for brevity */
return this.View(model);
}
我的控制器源自基础 class,SecuredController
又源自 Controller
。 SecurityPrincipal
是 SecuredController
的 属性,包含有关当前用户的大量 Active Directory 数据。
为了消除重复代码,理想情况下我想将 if {...}
块中包含的功能移动到基本 class 方法中,但我想不出任何方法这样做,因为方法的 return 类型必须是 ActionResult
,导致像这样笨拙的东西:
if ((var result = this.RequireReadWrite()) != null)
{
return result;
}
任何人都可以建议一种方法来做到这一点,还是我只是运气不好?
如评论中所述,特别注意安全性 cross cutting concern we've suggested using MVC Action Filters 将应用于您的用例和设计。
Microsoft 的文档提供了非常丰富的信息,并且可以在网上找到更多关于如何使用 MVC 过滤器 的示例。我将尝试提供一个示例,但这将基于对您的软件架构的许多假设,因为我根本不了解这方面的知识。
您可以创建以下 class:
public class SecuredFilterAttribute : AuthorizeAttribute
{
...
}
如果使用 Dependency Injection 框架,您可以注入 SecurityPrincipal
服务。但同样,我不知道您的应用程序的体系结构,因此如何创建该依赖项取决于您。
当覆盖 AuthorizeCore
时,你可以这样实现它:
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return !this.SecurityPrinciple.IsReadOnlyUser;
}
并且在未授权时重写 HandleUnauthorizedRequest
方法进行重定向:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
var redirectRoute = ...; //your route to redirect to an unauthorized page
filterContext.Result = new RedirectToRouteResult(redirectRoute);
//do some other things, for example, setting some tempdata information
}
同样,如何使用此 Filter 取决于您。您可以在全球范围内注册它,或者在每个控制器或操作的基础上应用它。要在全球范围内注册它,请在您的启动中:
GlobalFilters.Filters.Add(new SecuredFilterAttribute());
考虑以下在我的许多控制器操作中重复出现的代码块。 (我主要关注方法体的前 6 行)。
[HttpGet]
public ActionResult OptOut()
{
var user = this.SecurityPrincipal;
if (user.IsReadOnlyUser)
{
this.TempData["ViewModel"] = new AuthorizationModel { User = user };
return this.RedirectToAction("NotAuthorized", "Authorization");
}
var model = /* Elided for brevity */
return this.View(model);
}
我的控制器源自基础 class,SecuredController
又源自 Controller
。 SecurityPrincipal
是 SecuredController
的 属性,包含有关当前用户的大量 Active Directory 数据。
为了消除重复代码,理想情况下我想将 if {...}
块中包含的功能移动到基本 class 方法中,但我想不出任何方法这样做,因为方法的 return 类型必须是 ActionResult
,导致像这样笨拙的东西:
if ((var result = this.RequireReadWrite()) != null)
{
return result;
}
任何人都可以建议一种方法来做到这一点,还是我只是运气不好?
如评论中所述,特别注意安全性 cross cutting concern we've suggested using MVC Action Filters 将应用于您的用例和设计。
Microsoft 的文档提供了非常丰富的信息,并且可以在网上找到更多关于如何使用 MVC 过滤器 的示例。我将尝试提供一个示例,但这将基于对您的软件架构的许多假设,因为我根本不了解这方面的知识。
您可以创建以下 class:
public class SecuredFilterAttribute : AuthorizeAttribute
{
...
}
如果使用 Dependency Injection 框架,您可以注入 SecurityPrincipal
服务。但同样,我不知道您的应用程序的体系结构,因此如何创建该依赖项取决于您。
当覆盖 AuthorizeCore
时,你可以这样实现它:
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return !this.SecurityPrinciple.IsReadOnlyUser;
}
并且在未授权时重写 HandleUnauthorizedRequest
方法进行重定向:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
var redirectRoute = ...; //your route to redirect to an unauthorized page
filterContext.Result = new RedirectToRouteResult(redirectRoute);
//do some other things, for example, setting some tempdata information
}
同样,如何使用此 Filter 取决于您。您可以在全球范围内注册它,或者在每个控制器或操作的基础上应用它。要在全球范围内注册它,请在您的启动中:
GlobalFilters.Filters.Add(new SecuredFilterAttribute());