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.NonSerializedAttribute
attribute - New automatically generated instance properties if they are not marked with the
System.NonSerializedAttribute
attribute
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
GetObjectData
static method of thePX.Common.ReflectionSerializer
class. This class is responsible for Acumatica reflection-based serialization and deserialization of data. - A call to the base
GetObjectData
method, as shown in the following example.base.GetObjectData(info, context);
Note: In older versions of Acumatica ERP, there is no
PX.Common.ReflectionSerializer
class because it was added later during refactoring. ThePX.Common.PXReflectionSerializer
class 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);
}
}