linqpad and custom IPrincipal serializable
Asked Answered
K

3

6

I'm using LINQPad to test code (what a great product, I must say) but now I'm encountering an exception when I try to set the Thread.CurrentPrincipal to a custom IPrincipal that is marked with the SerializableAttribute following a sample that demonstrate the problem

void Main()
{
    Thread.CurrentPrincipal = new MyCustomPrincipal();
}

// Define other methods and classes here
[Serializable]
public class MyCustomPrincipal : IPrincipal
{
    public bool IsInRole(string role)
    {
        return true;
    }

    public IIdentity Identity 
    { 
        get
        {
            return new WindowsIdentity("RECUPERA\\m.casamento");
        }
    }
}

When I run this code in LINQPad (C# Program as Language) I get the following exception

Type is not resolved for member 'UserQuery+MyCustomPrincipal,query_nhxfev, Version=0.0.0.0, 
Culture=neutral, PublicKeyToken=null' 
RuntimeMethodInfo: PluginWindowManager.get_Form ()

If I remove the Serializable attribute everything goes fine. It seems a problem related with the AppDomain architecture that LINQPad uses and the inability of the framework to find the assembly that define the MyCustomPrincipal. Also, I believe that defining MyCustomPrincipal into another assembly and putting it into the GAC would solve the problem, but that's not an option for me. Anyone have an idea ?

Thanks, Marco

EDIT: I don't know if it could help, but I've had the same problem with SqlDependency.Start: putting Serializable on IPrincipal made the framework to throw an error complaining that it can't find the assembly that define the type of IPrincipal. I've solved with an ignominious hack:

System.Security.Principal.IPrincipal principal;
principal = System.Threading.Thread.CurrentPrincipal;

System.Threading.Thread.CurrentPrincipal = null;
try
{
    SqlDependency.Start(connectionString);
        m_SqlDependencyStarted = true;
}
catch (Exception ex)
{
    throw (ex);
}
finally
{
    System.Threading.Thread.CurrentPrincipal = principal;
}
Koffman answered 13/7, 2012 at 14:2 Comment(3)
This does look like a LINQPad issue. I'll look into it in more detail and post back.Embolectomy
@JoeAlbahari do you have any update on this ? It's really annoying and I didn't find any workaroundKoffman
I thought I'd found an answer here: #11490173, but it doesn't work for LINQPad because cross-domain calls are initiated from both sides. A lot of comms goes on in LINQPad between the host and worker domains - there are more than a dozen methods - so it's not just a question of hacking around a single call.Embolectomy
D
0

One trick you could use is to strong name the assembly containing the custom principal and put that into the Global Assembly Cache. That way any application can find the assembly you want, it isn't an ideal solution because you will have to remove it again afterwards. Anyway to install into the GAC if you have Visual Studio installed run up a VS command prompt and run the following:

gacutil -i nameofassembly.dll

Demarche answered 31/12, 2012 at 10:39 Comment(1)
Thanks for your answer, I've already tried it and it works. I consider it more of a workaround that a real solution, but it's better than nothing. I'm flagging this as the answer, nevertheless.Koffman
D
0

Stab in the dark but could it be a signing thing due to crossing assemblies?

Doody answered 14/8, 2012 at 17:47 Comment(1)
maybe, but how can I sign an assembly that exists only in memory ? It should be done inside of LINQPad, shouldn't it ?Koffman
E
0

This seems to be a serialization problem within LinqPad. i see Joseph Albahari, creator of Linqpad, has confirmed this in your comments.

Bottom line: we need a fix in LinqPad for this. I don't know of any work around.

Exhilarant answered 30/8, 2012 at 19:26 Comment(0)
D
0

One trick you could use is to strong name the assembly containing the custom principal and put that into the Global Assembly Cache. That way any application can find the assembly you want, it isn't an ideal solution because you will have to remove it again afterwards. Anyway to install into the GAC if you have Visual Studio installed run up a VS command prompt and run the following:

gacutil -i nameofassembly.dll

Demarche answered 31/12, 2012 at 10:39 Comment(1)
Thanks for your answer, I've already tried it and it works. I consider it more of a workaround that a real solution, but it's better than nothing. I'm flagging this as the answer, nevertheless.Koffman

© 2022 - 2024 — McMap. All rights reserved.