Gurmeet
Gurmeet

Reputation: 3314

where we can override .net base class library methods

I need to override default Functions of Base class to implement some custom behavior. For example i need to handle unauthorized requests in an MVC4 Application. I searched and found some answer which are overriding default methods of AuthorizeAttribute class as below:

Default basse class:

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);
}

Overriding 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" };
    }
}

But i have few questions in mind that i would like to get explained before using this functionlality. I know these are very basic questions but still have some confusion in mind about these.

Questions:

  1. Where we can overide Base class methods, Means do i need to add a new c# class file and then override BCL Methods?

  2. if i override, then i have to use [CustomAuthorization] signature on all methods where i have used [Authorize] signature. Is there any way to overirde default functionality of HandleUnauthorizedRequest without making any signature change?

  3. if we have to override functionality of some default BCL Methods which is required for some particular page liek .ToString() then should we override these BCL methods in that class itself. Is it correct ?

Any answers or suggestions will be appreciated. Thank you.

Upvotes: 0

Views: 1660

Answers (3)

Marc Gravell
Marc Gravell

Reputation: 1063328

I think most of your question comes down to:

can I monkey-patch in .NET?

to which the answer is simply "no". You must use known and published extension points. Sometimes that means override in a sub-class; sometimes that means changing some provider (usually implementing an interface), and sometimes it means hooking an event. Sometimes, you simply can't do it (although in the specific example of MVC4, even if there isn't an extension point you could just fork the source code itself and recompile).

Upvotes: 1

Wiktor Zychla
Wiktor Zychla

Reputation: 48280

Q1. Yes

Q2. Yes and no. Normally to use the subclass, you'd have to make it explicit, i.e. replace all existing attributes with subclass attributes.

However, MVC is kind of specific as it has been designed so that it allows you to hook into many internals. In particular, the internal resolver, that is called when infrastructure elements are created, can be customized.

Take a look at this tutorial

http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-dependency-injection#Exercise3

First, they set up a custom dependency resolver (IDependencyResolver). The resolver is called by MVC everytime it needs something. When filters are about to be used, MVC asks the resolver for a IFilterProvider. The provider then is responsible for creating a filter. And this is where your custom filter provider could be smart and return your inherited class instances instead of base class instances.

Although technically possible, the question remains - would it be clean and understandable enough? Since the resolver is configured externally to controllers/actions, just looking at controllers and actions code would not reveal that filters are replaced by the provider. This doesn't sound good, sooner or later someone could possibly make a major mistake because of this confusion. The recommendation would be then to make it explicit - use subclass filters in an explicit way.

Q3. Yes

Upvotes: 1

stevethethread
stevethethread

Reputation: 2524

Gerry. In regards to overriding base class methods, you can only do so if the method is marked as virtual. Yes, you need to inherit from the base class, and override the virtual methods as necessary. You can hide non-virtual methods by making use of the 'new' keyword. Also, classes marked as sealed cannot be inherited.

Yes, you will need to create a custom Auth attribute, and change all your usages, although an alternative would be to register it as a global filter, but that would then be applied to every action, which you may not want.

You are correct, if you want to override something like .ToString(), then you do it the child/inheriting classes.

Upvotes: 1

Related Questions