PRB: You Cannot Use XML Serialization on a Class with Declarative Security (326971)



The information in this article applies to:

  • Microsoft .NET Framework Class Libraries 1.0 SP2
  • Microsoft Windows .NET Framework Class Libraries 1.1
  • Microsoft .NET Framework Class Libraries 1.0
  • Microsoft .NET Framework Class Libraries 1.0 SP1

This article was previously published under Q326971

SYMPTOMS

The XmlSerializer class (under the System.Xml.Serialization namespace) does not support serializing class members that have declarative security attributes. This prevents the XmlSerializer class from accidentally circumventing certain kinds of declarative security. If the XmlSerializer is constructed for a type that contains members with declarative security attributes, it throws an exception, and you receive an exception error message that is similar to following:
The property "..." on type "..." cannot be serialized because it is decorated with declarative security permission attributes.

STATUS

This behavior is by design.

MORE INFORMATION

For example, TestClass has a password property that has declarative security attributes:
public class TestClass 
{
   string password;
   public string Password 		
  {
    [SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
    get { return password; }
			
    [SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
    set { password = value; }
 }
}
				
The following code uses the XmlSerializer to serialize an object of TestClass:
using System;
using System.Xml.Serialization;
using System.IO;
using System.Security.Permissions;

namespace ConsoleApplication1
{
	public class TestClass 
	{
		string password;

		public string Password 		
		{
			[SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
			get { return password; }
			[SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
			set { password = value; }
		}
	

		static void Main(string[] args)
		{
			try 
			{
				TestClass tc = new TestClass();
				tc.Password = "mypassword";
				
				// This line throws an exception because of the declarative security
				// on the get and set methods of TestClass.Password
				XmlSerializer s = new XmlSerializer(typeof(TestClass));
				s.Serialize(Console.Out, tc);				
			}
			
			catch (Exception e) 
			{
				Console.WriteLine(e.ToString());
			}
			Console.Read();
		}
	}
}


				
This code throws an exception, and you receive an exception error message that is similar to the following:
The property 'Password' on type 'ConsoleApplication1.TestClass' cannot be serialized because it is decorated with declarative security permission attributes. Consider using imperative asserts or demands in the property accessors.
To serialize TestClass with the XmlSerializer, you must use an imperative Demand method instead of a declarative Demand method. For example:
public class TestClass1 
{
	string password;

	public string Password 		
	{
		get 
		{
			new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
			return password;
		}

		set 
		{
			new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
			password = value;
		}
	}
}
				

You can serialize the object of TestClass1 with the XmlSerializer without any exception.

NOTE: The System.Exception class has a few properties with declarative security attributes. When you use XmlSerializer to serialize an Exception object, an exception is raised, and you receive an error exception message that is similar to the following:
"The property 'Source' on type 'System.Exception' cannot be serialized because it is decorated with declarative security permission attributes. "
You receive this message when the full Exception information is returned.
catch (Exception e) 
{
	Console.WriteLine(e.ToString());
}
				
If you return the Exception (error message), you receive only the following error message:
There was an error reflecting 'System.Exception'.

Modification Type:MajorLast Reviewed:6/29/2004
Keywords:kbprb KB326971 kbAudDeveloper