| Severity | Error |
| Reported by | PostSharp |
| Message | Cannot serialize the aspects: <ExceptionMessage>. |
Cause
PostSharp creates the aspect instances at build time, initializes them, for example in CompileTimeInitialize, and serializes them into a resource of the assembly. At run time, the aspects are deserialized from this resource instead of being created again. Every field of an aspect that is not excluded from serialization must therefore hold a serializable value.
When the serializer throws an exception, PostSharp reports LA0001, and <ExceptionMessage> is the message of this exception. With [PSerializableAttribute], the most common exception says that PostSharp cannot find a serializer for a type: a field of the aspect holds an object of a type that is neither serializable by PostSharp nor marked with [PSerializableAttribute]. The message has no location, because the aspects of the assembly are serialized together; the type in the exception message tells you which field to look at.
In the following example, the [Audit] aspect stores an AuditSettings object at build time, but AuditSettings is not serializable.
using System;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Serialization;
namespace Errors.LA0001_Error;
public class AuditSettings
{
public AuditSettings( string category )
{
this.Category = category;
}
public string Category { get; }
}
[PSerializable]
public class AuditAttribute : OnMethodBoundaryAspect
{
// AuditSettings is not serializable, so PostSharp cannot store the aspect in the assembly.
private AuditSettings? settings;
public override void CompileTimeInitialize( MethodBase method, AspectInfo aspectInfo )
{
this.settings = new AuditSettings( method.DeclaringType!.Name );
}
public override void OnEntry( MethodExecutionArgs args )
{
Console.WriteLine( $"[{this.settings!.Category}] {args.Method.Name}" );
}
}
public class OrderService
{
[Audit]
public void PlaceOrder( string product )
{
Console.WriteLine( $"Order placed for {product}." );
}
}
public static class Program
{
public static void Main()
{
new OrderService().PlaceOrder( "Coffee" );
}
}
error LA0001: Cannot serialize the aspects: Cannot find a serializer for type 'Errors.LA0001_Error.AuditSettings'.
Resolution
- Make the type of the field serializable, for example with [PSerializableAttribute]. A type marked with this attribute must itself have serializable fields.
- When the value is only needed at run time, mark the field with [PNonSerializedAttribute] and initialize it in RuntimeInitialize instead.
In the following example, AuditSettings is marked with [PSerializableAttribute], and the aspect gets the category that it computed at build time.
using System;
using System.Reflection;
using PostSharp.Aspects;
using PostSharp.Serialization;
namespace Errors.LA0001_Fixed;
// AuditSettings is serializable, so PostSharp can store the aspect in the assembly.
[PSerializable]
public class AuditSettings
{
public AuditSettings( string category )
{
this.Category = category;
}
public string Category { get; private set; }
}
[PSerializable]
public class AuditAttribute : OnMethodBoundaryAspect
{
private AuditSettings? settings;
public override void CompileTimeInitialize( MethodBase method, AspectInfo aspectInfo )
{
this.settings = new AuditSettings( method.DeclaringType!.Name );
}
public override void OnEntry( MethodExecutionArgs args )
{
Console.WriteLine( $"[{this.settings!.Category}] {args.Method.Name}" );
}
}
public class OrderService
{
[Audit]
public void PlaceOrder( string product )
{
Console.WriteLine( $"Order placed for {product}." );
}
}
public static class Program
{
public static void Main()
{
new OrderService().PlaceOrder( "Coffee" );
}
}
[OrderService] PlaceOrder
Order placed for Coffee.
See Also
Reference
PSerializableAttribute
PNonSerializedAttribute
Other Resources
Understanding Aspect Serialization
Understanding Aspect Lifetime and Scope