Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# - Custom Attribute not found from GetCustomAttribute from Interface

I am attempting to setup a custom attribute like the following:

[AttributeUsageAttribute(AttributeTargets.Method)]
public sealed class AuthorizationAttribute : Attribute
{
    public AuthorizationAttribute(bool required)
    {
        Required = required;
    }

    public bool Required;
}

In my service contract interface, I have a method like such:

[OperationContract]
[Authorization(true)]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "randommethod")]
ReturnObject RandomMethod();

When I do the following I see it in the list, but but the 'is' comparison, fails:

foreach(object attribute in methodInfo.GetCustomAttributes(true)) // Returns all 3 of my attributes.

if (attribute is AuthorizationAttribute) //Does not pass

I have tried to do the following that returns false:

Attribute.IsDefined(methodInfo, typeof(AuthorizationAttribute));
attribute.GetType().IsAssignableFrom(typeof(AuthorizationAttribute));

I have also done the following 2 things that returns null:

AuthorizationAttribute authAttribute = attribute as AuthorizationAttribute;
Attribute attribute = Attribute.GetCustomAttribute(methodInfo, typeof(AuthorizationAttribute));

I am not sure what I am doing wrong here. It seems like it should work, but I am sure I am making a simple mistake somewhere. Any insight?

Thanks for any assistance.

Edit: I am not sure if it adds any meaning, but the AuthorizationAttribute declaration exists in a different project from my services project. The Service Contract interface exists in the same project as the AuthorizationAttribute.

I tried doing a cast and got the following exception:

[A]Lib.OAuth.AuthorizationAttribute cannot be cast to [B]Lib.OAuth.AuthorizationAttribute. 
Type A originates from 'Lib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the
context 'LoadNeither' at location 'F:\RestServices\bin\Lib.dll'. Type B originates from 'Lib,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 
'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\oauth_rest\951069b9
\9f7b77fe\assembly\dl3\54c48906\f928a6ad_01facb01\Lib.dll'.

Any ideas?

like image 343
Brandon Avatar asked Apr 13 '11 16:04

Brandon


2 Answers

The exception contains the answer:

Type A originates...at location 'F:\RestServices\bin\Lib.dll'. Type B originates...at location 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\oauth_rest\951069b9 \9f7b77fe\assembly\dl3\54c48906\f928a6ad_01facb01\Lib.dll'

The issue is that the Lib.OAuth.AuthorizationAttribute type which attributes your method is found in an assembly that is different than the assembly loaded at runtime when you try to cast.

Is it possible that one of your projects is using an old version of Lib.dll?

like image 173
Wesley Wiser Avatar answered Nov 14 '22 13:11

Wesley Wiser


Thanks to Wesley's response, I was able to figure this out. It is more of a 'duh' moment than anything.

I was using some example code for reflection to load an assembly via the Assembly.LoadFile(...) method. The problem is that since my assembly was not registered with the GAC, it was reading the local copy on the IIS server and the comparison failed.

For reference, this was my solution:

Assembly.GetExecutingAssembly();

Once I did that, everything worked.

like image 20
Brandon Avatar answered Nov 14 '22 14:11

Brandon