i have implemented a custom IIdentity object. The class already implements the ISerializable interface and is annotated with a SerializableAttribute. After installing the .NET Framework 4.5 (with Visual Studio 2012) the Web Application fails to serialize
the identity object. If already adjusted the code of the GetObjectData as described in another thread (http://forums.asp.net/p/1469217/3402134.aspx). The implementation is now the following:
[Serializable] public class MyUser : IUser, IPrincipal, IIdentity, ISerializable
{
...
public void GetObjectData( SerializationInfo info, StreamingContext context )
{
bool isCrossApp = (context.State & StreamingContextStates.CrossAppDomain) == StreamingContextStates.CrossAppDomain;
if ( isCrossApp ) {
var genericIdentity = new GenericIdentity( Name, AuthenticationType );
var genericType = genericIdentity.GetType();
info.SetType( genericType );
var serializableMembers = FormatterServices.GetSerializableMembers( genericType, context );
var serializableValues = FormatterServices.GetObjectData( genericIdentity, serializableMembers );
for ( int i = 0; i < serializableMembers.Length; i++ ) {
var fieldName = serializableMembers[i].Name;
var fieldValue = serializableValues[i];
info.AddValue( fieldName, fieldValue );
}
}
else {
throw new NotSupportedException();
}
}
However when i run the application either in Visual Studio 2010 or 2012 I get an exception when the web server is deserializing the object. The exception occurs in GenericIdentity.OnDeserializedMethod(StreamingContext context). The cause of the exception seems to
be that the property Claims is not initialized.
I don't have this problem if the web application is running in the IIS.
Does anyone have a hint how to workaround this exception using the integrated Development Server?
This was described
here. You mention claims -- are you using WIF? I ran into this issue with the ClaimsIdentity that WIF uses and
here was my workaround.
thanks for your help but I think the link you provided is not describing exactly the same problem. While my exception is caused for the same reason (serialization of a custom IIdentity object in the development server) the problem is specific to the .NET
framework 4.5. For .NET <= 4.0 the trick to use the GenericIdentity for cross app domain serialization worked pretty well.
The problem with .NET 4.5 is that the GenericIdentity is derived from the new class ClaimsIdentity. Although the code is still running with .NET 4.0 the new implementation is used under the hood i.e. you can't see the hierarchy in the visual studio object
browser but the debugger and reflector shows the derivation.
Furthermore the new GenericIdentity implements GenericIdentity.OnDeserializedMethod. This method accesses the base class Claims property without checking for null.
The problem is not related to WIF. Its just a IIdentity implementation that is used to define the user of the current request.
I found the following solution that works pretty well without haveing to update a GAC file after every recompile.
a) I Created a new class library WebDev with a strong name (I haven't tested if the strong name signing is really required). The class library contains only a single class: SimpleIdentity. The implementation is straight forward:
namespace WebDev
{
[Serializable]
public class SimpleIdentity : IIdentity
{
private string name;
private string type;
public SimpleIdentity( string name, string authentitcationType )
{
if ( name == null )
throw new ArgumentNullException( "name" );
if ( authentitcationType == null )
throw new ArgumentNullException( "authentitcationType" );
this.name = name;
this.type = authentitcationType;
}
private SimpleIdentity()
{
}
public string Name
{
get { return this.name; }
}
public string AuthenticationType
{
get { return this.type; }
}
public bool IsAuthenticated
{
get { return !string.IsNullOrEmpty( Name ); }
}
}
}
After compilation i placed the dll in the following two directories:
I our web project I included the class file and in our IIdentity Implementation i specified the assembly name in the serialization method GetObjectData.
void ISerializable.GetObjectData( SerializationInfo info, StreamingContext context )
{
bool isCrossApp = (context.State & StreamingContextStates.CrossAppDomain) == StreamingContextStates.CrossAppDomain;
if ( isCrossApp ) {
var genericIdentity = new WebDev.SimpleIdentity( this.Name, this.AuthenticationType );
var genericType = genericIdentity.GetType();
info.SetType( genericType );
info.AssemblyName = "WebDev, PublicKeyToken=1f56b122e0f1be80";
var serializableMembers = FormatterServices.GetSerializableMembers( genericType, context );
var serializableValues = FormatterServices.GetObjectData( genericIdentity, serializableMembers );
for ( int i = 0; i < serializableMembers.Length; i++ ) {
var fieldName = serializableMembers[i].Name;
var fieldValue = serializableValues[i];
info.AddValue( fieldName, fieldValue );
}
}
else {
throw new NotSupportedException();
}
}
This way the program runs in the development studio and i don't have to install the library in the global assembly cache.
I think this is the second best solution. My preferred solution would be some code that eliminates the need to place files in the programs directory. I still like to know if anyone knows a way to accomplish this.
Ralias
0 Points
3 Posts
Custom Identity problem after installing .NET 4.5 / NullReferenceException in GenericIdentity.OnD...
Aug 16, 2012 05:59 PM|LINK
Hello,
i have implemented a custom IIdentity object. The class already implements the ISerializable interface and is annotated with a SerializableAttribute. After installing the .NET Framework 4.5 (with Visual Studio 2012) the Web Application fails to serialize the identity object. If already adjusted the code of the GetObjectData as described in another thread (http://forums.asp.net/p/1469217/3402134.aspx). The implementation is now the following:
However when i run the application either in Visual Studio 2010 or 2012 I get an exception when the web server is deserializing the object. The exception occurs in GenericIdentity.OnDeserializedMethod(StreamingContext context). The cause of the exception seems to be that the property Claims is not initialized.
I don't have this problem if the web application is running in the IIS.
Does anyone have a hint how to workaround this exception using the integrated Development Server?
Thanks
Ralf
BrockAllen
All-Star
27534 Points
4907 Posts
MVP
Re: Custom Identity problem after installing .NET 4.5 / NullReferenceException in GenericIdentity...
Aug 16, 2012 06:36 PM|LINK
This was described here. You mention claims -- are you using WIF? I ran into this issue with the ClaimsIdentity that WIF uses and here was my workaround.
DevelopMentor | http://www.develop.com
thinktecture | http://www.thinktecture.com/
Ralias
0 Points
3 Posts
Re: Custom Identity problem after installing .NET 4.5 / NullReferenceException in GenericIdentity...
Aug 17, 2012 08:21 AM|LINK
Hi Allen,
thanks for your help but I think the link you provided is not describing exactly the same problem. While my exception is caused for the same reason (serialization of a custom IIdentity object in the development server) the problem is specific to the .NET framework 4.5. For .NET <= 4.0 the trick to use the GenericIdentity for cross app domain serialization worked pretty well.
The problem with .NET 4.5 is that the GenericIdentity is derived from the new class ClaimsIdentity. Although the code is still running with .NET 4.0 the new implementation is used under the hood i.e. you can't see the hierarchy in the visual studio object browser but the debugger and reflector shows the derivation.
Furthermore the new GenericIdentity implements GenericIdentity.OnDeserializedMethod. This method accesses the base class Claims property without checking for null.
The problem is not related to WIF. Its just a IIdentity implementation that is used to define the user of the current request.
Ralf
Ralias
0 Points
3 Posts
Re: Custom Identity problem after installing .NET 4.5 / NullReferenceException in GenericIdentity...
Aug 17, 2012 11:31 AM|LINK
I found the following solution that works pretty well without haveing to update a GAC file after every recompile.
a) I Created a new class library WebDev with a strong name (I haven't tested if the strong name signing is really required). The class library contains only a single class: SimpleIdentity. The implementation is straight forward:
namespace WebDev { [Serializable] public class SimpleIdentity : IIdentity { private string name; private string type; public SimpleIdentity( string name, string authentitcationType ) { if ( name == null ) throw new ArgumentNullException( "name" ); if ( authentitcationType == null ) throw new ArgumentNullException( "authentitcationType" ); this.name = name; this.type = authentitcationType; } private SimpleIdentity() { } public string Name { get { return this.name; } } public string AuthenticationType { get { return this.type; } } public bool IsAuthenticated { get { return !string.IsNullOrEmpty( Name ); } } } }After compilation i placed the dll in the following two directories:
I our web project I included the class file and in our IIdentity Implementation i specified the assembly name in the serialization method GetObjectData.
void ISerializable.GetObjectData( SerializationInfo info, StreamingContext context ) { bool isCrossApp = (context.State & StreamingContextStates.CrossAppDomain) == StreamingContextStates.CrossAppDomain; if ( isCrossApp ) { var genericIdentity = new WebDev.SimpleIdentity( this.Name, this.AuthenticationType ); var genericType = genericIdentity.GetType(); info.SetType( genericType ); info.AssemblyName = "WebDev, PublicKeyToken=1f56b122e0f1be80"; var serializableMembers = FormatterServices.GetSerializableMembers( genericType, context ); var serializableValues = FormatterServices.GetObjectData( genericIdentity, serializableMembers ); for ( int i = 0; i < serializableMembers.Length; i++ ) { var fieldName = serializableMembers[i].Name; var fieldValue = serializableValues[i]; info.AddValue( fieldName, fieldValue ); } } else { throw new NotSupportedException(); } }This way the program runs in the development studio and i don't have to install the library in the global assembly cache.
I think this is the second best solution. My preferred solution would be some code that eliminates the need to place files in the programs directory. I still like to know if anyone knows a way to accomplish this.
Ralf
PaulWar
Member
2 Points
1 Post
Re: Custom Identity problem after installing .NET 4.5 / NullReferenceException in GenericIdentity...
Dec 06, 2012 12:29 PM|LINK
Greetings, I encountered the same exact problem. Eventually, after some research I found that making my custom identity inherit from System.MarshalByRefObject the problem went away, I found a blog entry here http://www.logue.com.ar/blog/2007/12/cassini-serializationexception-type-is-not-resolved-for-member/ . Inheriting MarshalByRefObject solved the problem for me, and doesn't require Signing libraries and copying assemblies around, hopefully it will help you as well.