This document describes the PX1064 diagnostic.
| Code | Short Description | Type | Code Fix |
|---|---|---|---|
| PX1064 | The declaration of the exception class introduces new serializable fields but does not declare an override for the GetObjectData method. This will cause incorrect serialization of the exception data and will lead to runtime errors in Acumatica ERP. |
Error | Available |
Every class that is derived from the System.Exception class (including PXException-derived classes) and that declares new serializable data should always provide an override for the GetObjectData method.
This diagnostic considers data to be serializable if it is new data declared in the exception class that will be serialized by .Net serializers and Acumatica reflection-based serializers. This data includes the following:
- New instance fields if they are not marked with the
System.NonSerializedAttributeattribute - New automatically generated instance properties if they are not marked with the
System.NonSerializedAttributeattribute
For example, the following types of members are not considered serializable:
- Static fields and constants
- Static properties
- Calculated properties
- Properties with an explicit backing field, as shown in the following example
public int Property { get => _fieldFromBaseClass; set { _fieldFromBaseClass = value; } }
- Fields and properties marked as non-serializable, as shown in the following example
[field: NonSerialized] public int Property { get; set; }
The code fix generates the missing GetObjectData method override that contains the following statements:
- A call to the
GetObjectDatastatic method of thePX.Common.ReflectionSerializerclass. This class is responsible for Acumatica reflection-based serialization and deserialization of data. - A call to the base
GetObjectDatamethod, as shown in the following example.base.GetObjectData(info, context);
Note: In older versions of Acumatica ERP, there is no
PX.Common.ReflectionSerializerclass because it was added later during refactoring. ThePX.Common.PXReflectionSerializerclass will be used instead; the names of the methods are the same.
public sealed class PXNewSerializableAutoPropertiesException : PXBaseRedirectException
{
/// <summary>
/// Identifier of the document that should be signed
/// </summary>
public Guid FileId { get; private set; }
/// <summary>
/// View name from which the sign action is called
/// </summary>
public string ViewName { get; private set; }
public PXNewSerializableAutoPropertiesException(string viewName, Guid fileId) : base(fileId.ToString())
{
ViewName = viewName;
FileId = fileId;
}
private PXNewSerializableAutoPropertiesException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context)
{
FileId = (Guid)info.GetValue(nameof(FileId), typeof(Guid));
ViewName = info.GetString(nameof(ViewName));
}
}public sealed class PXNewSerializableAutoPropertiesException : PXBaseRedirectException
{
/// <summary>
/// Identifier of the document that should be signed
/// </summary>
public Guid FileId { get; private set; }
/// <summary>
/// View name from which the sign action is called
/// </summary>
public string ViewName { get; private set; }
public PXNewSerializableAutoPropertiesException(string viewName, Guid fileId) : base(fileId.ToString())
{
ViewName = viewName;
FileId = fileId;
}
private PXNewSerializableAutoPropertiesException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context)
{
FileId = (Guid)info.GetValue(nameof(FileId), typeof(Guid));
ViewName = info.GetString(nameof(ViewName));
}
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
ReflectionSerializer.GetObjectData(this, info);
base.GetObjectData(info, context);
}
}