我们可以覆盖.net基类库方法

时间:2014-01-23 08:15:50

标签: c# .net override

我需要覆盖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" };
    }
}

但我在使用此功能之前想要解释的问题很少。我知道这些是非常基本的问题,但对于这些问题仍然存在一些困惑。

问题:

  1. 我们可以覆盖Base类方法,我需要添加一个新的c#类文件,然后覆盖BCL方法吗?

  2. 如果我覆盖,那么我必须在我使用[授权]签名的所有方法上使用[CustomAuthorization]签名。有没有办法在不进行任何签名更改的情况下覆盖HandleUnauthorizedRequest的默认功能?

  3. 如果我们必须覆盖某些特定页面谎言 .ToString()所需的某些默认BCL方法的功能,那么我们应该在该类本身中覆盖这些BCL方法。这是正确的吗?

  4. 任何答案或建议将不胜感激。 谢谢。

3 个答案:

答案 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的具体例子中,即使没有扩展点,你也可以自己分叉源代码并重新编译)。