【问题标题】:OnDeserialized() is not called in .NET Core [closed].NET Core 中未调用 OnDeserialized() [关闭]
【发布时间】:2021-07-17 05:39:27
【问题描述】:

我有一个请求类,它具有三个属性,其中两个将从 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");
    }
}

【问题讨论】:

  • 我猜你可能习惯于使用 JSON.NET,但现在你使用的是 System.Text.Json(在这里添加适当的标签会很有帮助)。无论如何,拖车之间存在一些差异。 This migration documentation 涵盖了您提到的事件。
  • 是的,我正在使用 System.Text.Json。感谢您的洞察力!
  • OnSerializing 属于 System.Runtime.Serialization 命名空间,它是二进制序列化,这不适用于 System.Text.Json
  • 另请注意,ASP.NET 似乎与这个问题没有任何关系,我不确定 ASP.NET5 是什么。有 .NET 5,它与 .NET Core 不同。有 ASP.NET Core,它不同于 .NET Core 和 .NET 5。但是没有什么叫 ASP.NET 5,实际上标签信息说“不要再使用这个标签了”...

标签: c# asp.net-core .net-core system.text.json


【解决方案1】:

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

一种解决方案是添加适当的 NuGet 包并继续使用 JSON.NET(请参阅this question)。或者,Microsoft 已经生成了一个 migration documentation page 来处理从 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");
    }
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多