C# .NET核心中未调用OnDeserialized()

C# .NET核心中未调用OnDeserialized(),c#,asp.net-core,.net-core,system.text.json,C#,Asp.net Core,.net Core,System.text.json,我有一个请求类,它有三个属性,其中两个将从json请求体反序列化,最后一个将在反序列化后基于其他两个属性创建。我正在使用OnDeserialized()注释来实现这一点。然而,OnDeserialized注释似乎没有任何效果。下面是我的代码。请告知 public class BindUserRequest : IRequest<BindUserResponseDto> { [JsonIgnore] public PartitionKeyType Id { get;

我有一个请求类,它有三个属性,其中两个将从json请求体反序列化,最后一个将在反序列化后基于其他两个属性创建。我正在使用
OnDeserialized()
注释来实现这一点。然而,
OnDeserialized
注释似乎没有任何效果。下面是我的代码。请告知

public class BindUserRequest : IRequest<BindUserResponseDto>
{

    [JsonIgnore]
    public PartitionKeyType Id { get; set; }


    [Required]
    public string DeviceType { get; set; }

    [Required]
    public string DeviceId { get; set; }

    [OnSerializing()]
    void OnSerializingMethod(StreamingContext context)
    {
        DeviceType = Id.DeviceType;
        DeviceId = Id.DeviceId;
    }

    [OnDeserialized()]
    void OnDeserializedMethod(StreamingContext context)
    {
        Id = new PartitionKeyType { DeviceId = "123", DeviceType = "123" };
        System.Console.WriteLine("****OnDeserialized get called");
    }
}
公共类BindUserRequest:IRequest
{
[JsonIgnore]
public PartitionKeyType Id{get;set;}
[必需]
公共字符串设备类型{get;set;}
[必需]
公共字符串设备ID{get;set;}
[正在序列化()]
void OnSerializingMethod(StreamingContext上下文)
{
DeviceType=Id.DeviceType;
DeviceId=Id.DeviceId;
}
[OnDeserialized()]
void OnDeserializedMethod(StreamingContext上下文)
{
Id=new PartitionKeyType{DeviceId=“123”,DeviceType=“123”};
System.Console.WriteLine(“**OnDeserialized get called”);
}
}

您看到的问题是,从在ASP.NET Core 2.x中使用
JSON.NET
作为默认序列化程序,到在较新版本中使用
System.Text.JSON
。对于
JSON.NET
可以使用这些回调,但是对于
System.Text.JSON
它们不是序列化过程的一部分

一种解决方案是添加适当的NuGet包并继续使用JSON.NET(请参阅)。或者,微软已经为处理从JSON.NET到System.Text.JSON的变化提供了一个解决方案

该文档解释了将回调与System.Text.Json一起使用需要编写自定义转换器:

System.Text.Json
中,您可以通过编写自定义转换器来模拟回调。以下示例显示了POCO的自定义转换器。转换器包含的代码在与
Newtonsoft.Json
回调相对应的每个点显示消息

提供了以下示例代码:

public class WeatherForecastCallbacksConverter : JsonConverter<WeatherForecast>
{
    public override WeatherForecast Read(
        ref Utf8JsonReader reader,
        Type type,
        JsonSerializerOptions options)
    {
        // Place "before" code here (OnDeserializing),
        // but note that there is no access here to the POCO instance.
        Console.WriteLine("OnDeserializing");

        // Don't pass in options when recursively calling Deserialize.
        WeatherForecast forecast = JsonSerializer.Deserialize<WeatherForecast>(ref reader);

        // Place "after" code here (OnDeserialized)
        Console.WriteLine("OnDeserialized");

        return forecast;
    }

    public override void Write(
        Utf8JsonWriter writer,
        WeatherForecast forecast, JsonSerializerOptions options)
    {
        // Place "before" code here (OnSerializing)
        Console.WriteLine("OnSerializing");

        // Don't pass in options when recursively calling Serialize.
        JsonSerializer.Serialize(writer, forecast);

        // Place "after" code here (OnSerialized)
        Console.WriteLine("OnSerialized");
    }
}
公共类WeatherForecastCallbackConverter:JsonConverter
{
公共天气预报已读(
参考Utf8JsonReader读取器,
类型类型,
JsonSerializerOptions(可选)
{
//将“before”代码放在此处(序列化),
//但是请注意,这里没有访问POCO实例的权限。
Console.WriteLine(“序列化”);
//递归调用反序列化时不要传入选项。
WeatherForecast=JsonSerializer.Deserialize(参考读取器);
//在此处放置“之后”代码(已序列化)
Console.WriteLine(“序列化”);
收益预测;
}
公共覆盖无效写入(
Utf8JsonWriter,
WeatherForecast预测,JSONSerializeProptions选项)
{
//在此处放置“之前”代码(序列化)
Console.WriteLine(“OnSerialization”);
//递归调用Serialize时不要传入选项。
序列化(编写器、预测);
//在此处放置“后”代码(已序列化)
Console.WriteLine(“OnSerialized”);
}
}

然后,您可以在这里添加额外的序列化代码来处理您的用例。请注意,这需要使用
[JsonConverter(type)]
属性在类本身上注册,或者通过在序列化程序的转换器集合中注册来注册。

我猜您可能已经习惯了使用JSON.NET,但现在使用的是System.Text.JSON(在这里添加适当的标记会很有帮助)。不管怎样,这两件东西之间有一些区别。涵盖您提到的事件。是的,我使用的是System.Text.Json。谢谢你的洞察力!OnSerialization属于System.Runtime.Serialization命名空间,它是二进制序列化,这不适用于System.Text.JSONALO。请注意,ASP.NET似乎与此问题无关,我不确定ASP.NET5是什么。还有.NET5,它不同于.NETCore。有ASP.NET内核,它不同于.NET内核和.NET 5。但是没有所谓的ASP.NET 5,事实上标签信息上写着“不要再使用这个标签”。。。