我需要覆盖默认的 Base 类函数来实现一些自定义行为。例如,我需要在 MVC4 应用程序中处理未经授权的请求。我搜索并找到了一些覆盖 AuthorizeAttribute 类的默认方法的答案,如下所示:
默认 basse 类:
public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
{
public AuthorizeAttribute();
public string Roles { get; set; }
public override object TypeId { get; }
public string Users { get; set; }
protected virtual bool AuthorizeCore(HttpContextBase httpContext);
protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext);
public virtual void OnAuthorization(AuthorizationContext filterContext);
protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext);
}
覆盖 HandleUnauthorizedRequest:
public class CustomAuthorizationAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
// You need to set this action result to something other than a HttpUnauthorizedResult,
// this result will cause the redirection to the login page
// Forbidden request... does not redirect to login page
// filterContext.Result = new HttpStatusCodeResult(403);
filterContext.Result = new ErrorActionResult { ErrorMessage = "Unauthorized Access" };
}
}
但是我想知道在使用这个功能之前我想要解释的几个问题。我知道这些是非常基本的问题,但对于这些问题仍然存在一些困惑。
问题:
-
在我们可以覆盖 Base 类方法的地方,我需要添加一个新的 c#类文件,然后覆盖 BCL 方法吗?
-
如果我覆盖,那么我必须在我使用[6]签名的所有方法上使用[5]签名。有没有办法在不进行任何签名更改的情况下覆盖 HandleUnauthorizedRequest 的默认功能?
-
如果我们必须覆盖某些特定页面 liek **.ToString()**所需的某些默认 BCL 方法的功能,那么我们应该在该类本身中覆盖这些 BCL 方法。这是对的吗 ?
任何答案或建议将不胜感激。谢谢。
3 回答
Q1。是
Q2。是的,不是。通常使用子类,你必须明确,i.e。用子类属性替换所有现有属性。
但是,MVC 是一种特殊的,因为它的设计使它可以挂钩到许多内部。特别是,可以自定义在创建基础结构元素时调用的内部解析程序。
看一下本教程
http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-dependency-injection#Exercise3
首先,他们设置了一个自定义依赖项解析器(
IDependencyResolver
)。每次需要时,MVC 都会调用解析器。当即将使用过滤器时,MVC 要求解析器输入IFilterProvider
。然后,提供者负责创建过滤器。这是您的自定义筛选器提供程序可以是智能的,并返回继承的类实例而不是基类实例。虽然技术上可行,但问题仍然存在 - 它是否干净且可以理解?由于解析器在 controllers/actions 外部配置,因此仅查看控制器和操作代码不会显示提供程序替换了过滤器。这听起来不太好,迟早有人可能会因为这种混乱而犯下重大错误。然后建议将其显式化 - 以显式方式使用子类过滤器。
Q3。是
格里。关于覆盖基类方法,只有在方法标记为虚拟时才能执行此操作。是的,您需要从基类继承,并根据需要覆盖虚拟方法。您可以使用'new'关键字隐藏 non-virtual 方法。此外,标记为已密封的类不能继承。
是的,您需要创建一个自定义 Auth 属性,并更改所有用法,但另一种方法是将其注册为全局过滤器,但这会应用于您可能不需要的每个操作。
你是对的,如果你想覆盖像.ToString()这样的东西,那你就做 child/inheriting 类。
我想你的大部分问题都归结为:
答案只是“不”。您必须使用已知和已发布的扩展点。有时这意味着在 sub-class 中
override
;有时这意味着更改某些提供程序(通常是实现接口),有时它意味着挂钩事件。有时,你只是不能这样做(虽然在 MVC4 的具体例子中,即使没有扩展点,你也可以自己分叉源代码并重新编译)。