我需要覆盖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方法吗?
如果我覆盖,那么我必须在我使用[授权]签名的所有方法上使用[CustomAuthorization]签名。有没有办法在不进行任何签名更改的情况下覆盖HandleUnauthorizedRequest的默认功能?
如果我们必须覆盖某些特定页面谎言 .ToString()所需的某些默认BCL方法的功能,那么我们应该在该类本身中覆盖这些BCL方法。这是正确的吗?
任何答案或建议将不胜感激。 谢谢。
答案 0 :(得分:1)
格里。关于覆盖基类方法,只有在方法标记为虚拟时才能执行此操作。是的,您需要从基类继承,并根据需要覆盖虚拟方法。您可以使用'new'关键字隐藏非虚拟方法。此外,标记为已密封的类不能继承。
是的,您需要创建一个自定义Auth属性,并更改所有用法,但另一种方法是将其注册为全局过滤器,但这会应用于您可能不需要的每个操作。
你是对的,如果你想覆盖类似.ToString()的东西,那么你就可以使用子/继承类。
答案 1 :(得分:1)
Q1。是
Q2。是的,不是。通常使用子类,您必须使其显式化,即用子类属性替换所有现有属性。
然而,MVC是一种特定的,因为它的设计使它可以让你挂钩到许多内部。特别是,可以自定义在创建基础结构元素时调用的内部解析程序。
看一下本教程
http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-dependency-injection#Exercise3
首先,他们设置了自定义依赖项解析器(IDependencyResolver
)。每次需要时,MVC都会调用解析器。当即将使用过滤器时,MVC会向解析器请求IFilterProvider
。然后,提供者负责创建过滤器。这是您的自定义筛选器提供程序可以是智能的,并返回继承的类实例而不是基类实例。
虽然技术上可行,但问题仍然存在 - 它是否干净且可以理解?由于解析器是在控制器/操作外部配置的,因此仅查看控制器和操作代码不会显示提供程序替换过滤器。这听起来不太好,迟早有人可能会因为这种混乱而犯下重大错误。然后建议将其显式化 - 以明确的方式使用子类过滤器。
Q3。是
答案 2 :(得分:1)
我认为你的大部分问题都归结为:
我可以在.NET中使用monkey-patch吗?
答案简直就是“不”。您必须使用已知和已发布的扩展点。有时这意味着子类中的override
;有时这意味着更改某些提供程序(通常是实现接口),有时它意味着挂钩事件。有时,你只是不能做到(虽然在MVC4的具体例子中,即使没有扩展点,你也可以自己分叉源代码并重新编译)。