Back to Devexpress

Reporting — Safe Deserialization

xtrareports-404485-safe-deserialization.md

latest7.9 KB
Original Source

Reporting — Safe Deserialization

  • Aug 20, 2025
  • 4 minutes to read

DevExpress controls automatically detect potentially unsafe data types and block deserialization to address security-related issues. The NonTrustedTypeDeserializationException is thrown if a reporting control attempts to load an unsafe data type.

This article describes serialization/deserialization best practices specific to DevExpress Reporting components. Review the following help section for general security considerations related to all DevExpress components: General – Safe Deserialization.

DevExpress Reporting controls deserialize the following data types automatically:

  • Custom controls saved in XML/REPX.
  • Complex type values for properties marked with the XtraSerializableProperty attribute (for example, a reference to an object). Read the following topic for additional information in this regard: How to serialize a custom property of a DevExpress control descendant.
  • System.Object type properties (such as the Tag property) for simple data types such as integer, float, double, decimal, bool, string, etc.

Deserialize Custom Types

A custom type must be serialized to and deserialized from a string. Use IOneTypeObjectConverter to serialize the following custom types:

  • A complex parameter value (such as IList or IDictionary).
  • The control’s Tag property that contains a custom type (any type except primitive, string, decimal, date-time, etc.).

You should explicitly trust any bound data type your report references. If a custom type instance is a container for data types, use IObjectDataSerializer to serialize the custom type along with its content. Read the following section for additional information: Deserialize Data Sources.

Important

Do not use the BinaryFormatter to serialize/deserialize data. The BinaryFormatter is not secure and is not recommended for data processing purposes. Read the following topic for additional information: Deserialization Risks in Use of BinaryFormatter and Related Types.

Example

The following example serializes/deserializes the tag property value (determines whether to display time in the parameter value of the Parameter Editor.

Implement the IOneTypeObjectConverter interface and register the converter at application startup:

csharp
using System.Collections.Generic;
using DevExpress.Utils.Serializing.Helpers;

var app = builder.Build();

// Register a converter for the Tag property with a custom value of the ParameterEditorSettings type.
ObjectConverter.Instance.RegisterConverter(new ParameterEditorSettingsConverter());

app.Run();

sealed class ParameterEditorSettingsConverter : IOneTypeObjectConverter {
    public Type Type => typeof(ParameterEditorSettings);

    public object FromString(string str) {
        return JsonSerializer.Deserialize<ParameterEditorSettings>(str);
    }

    public string ToString(object obj) {
        return JsonSerializer.Serialize(obj);
    }
}

Deserialize Data Sources

Data loading-related restore operations for the following data source types generate security warnings if the following data sources use untrusted types:

Use IObjectDataSerializer to serialize custom data sources.

Example

The example below creates and registers a custom serializer for an object data source.

Implement and register a custom serializer (EmployeeListSerializer) that implements safe serialization/deserialization of the Employee data source type.

csharp
using System.Collections.Generic;
using DevExpress.Utils.Serializing;

var app = builder.Build();

// Allow custom data source serialization.
DevExpress.Utils.DeserializationSettings.RegisterTrustedClass(typeof(EmployeeDataSource));
// Register a custom serializer for Employee.
ObjectDataSerializer.Register<Employee>(new EmployeeListSerializer());

app.Run();

}
sealed class EmployeeListSerializer : IObjectDataSerializer {
    public bool CanDeserialize(string value, string typeName) {
        return typeName == typeof(List<Employee>).FullName;
    }

    public bool CanSerialize(object data) {
        return data is List<Employee>;
    }

    public object Deserialize(string value, string typeName) {
        if(typeName == typeof(List<Employee>).FullName)
            return JsonSerializer.Deserialize<List<Employee>>(value);
        throw new NotSupportedException();
    }

    public string Serialize(object data) {
        return JsonSerializer.Serialize(data);
    }
}

To allow data source serialization, explicitly trust the data source type at application startup.

csharp
var app = builder.Build();

// Allow custom data source serialization.
DevExpress.Utils.DeserializationSettings.RegisterTrustedClass(typeof(EmployeeDataSource));

app.Run();
csharp
public partial class EmployeesReport : DevExpress.XtraReports.UI.XtraReport {
    public EmployeesReport() {
        // ...
        this.objectDataSource1.DataSource = typeof(WebEFCoreApp.Data.EmployeeDataSource);
        // ...
    }
}

Deserialize Report Parameters

Implement a type converter to convert custom types to/from a string to deserialize complex parameter values (for example, IList, IDictionary). The DevExpress serialization/deserialization mechanism invokes the type converter whenever it encounters a registered custom type.

Example

The example below creates a custom type converter (DictionaryConverter).

Implement the IOneTypeObjectConverter interface and register the converter at application startup.

csharp
using DevExpress.Utils.Serializing.Helpers;

var app = builder.Build();

// Register a converter for the custom parameter of the Dictionary<string, int> type.
ObjectConverter.Instance.RegisterConverter(new DictionaryConverter());

app.Run();

sealed class DictionaryConverter : IOneTypeObjectConverter {
    public Type Type => typeof(Dictionary<string, int>);

    public object FromString(string str) {
        return JsonSerializer.Deserialize<Dictionary<string, int>>(str);
    }

    public string ToString(object obj) {
        return JsonSerializer.Serialize(obj);
    }
}

See Also

DevExpress Reporting - Security Considerations

Security - What You Need to Know

Reporting for WPF - How to Enable End Users to Load Custom Assemblies to the Entity Framework Context