You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Azure EventGridEvent忽略NewtonSoft.Json序列化配置的问题

问题根因

新版Azure.Messaging.EventGrid SDK中的EventGridPublisherClient默认使用System.Text.Json完成序列化工作,完全不会识别Newtonsoft.Json(Json.NET)体系下的[JsonProperty]、[JsonConverter]等特性,也不会读取你全局给Newtonsoft.Json配置的序列化规则,这就是属性名映射、枚举转字符串配置全部失效的核心原因。
至于[DataMember]特性不生效,是因为System.Text.Json默认不会读取该特性的配置,除非你手动开启对应支持。

可用解决方案

你可以根据自己的项目场景选以下任意一种方案:

方案1:替换为System.Text.Json对应特性(零额外代码,最简便)

如果项目没有强依赖Newtonsoft.Json的特殊序列化规则,直接把实体类上的Newtonsoft特性替换为System.Text.Json的对应特性即可,不需要修改其他发送逻辑:

using System.Text.Json.Serialization;

public class CuData 
{
    public enum CancellationTypes
    {
        Regular,
        Special,
        Relocation
    }

    [JsonPropertyName("type")]
    [JsonConverter(typeof(JsonStringEnumConverter))]
    public CancellationTypes CancellationType { get; set; }
}

注意这里的JsonStringEnumConverter来自System.Text.Json.Serialization命名空间,不要和Newtonsoft下的同名类混淆,修改后默认序列化输出就和预期的{"type":"Regular"}完全一致。

方案2:配置客户端使用Newtonsoft.Json序列化(适合全局统一用Newtonsoft的项目)

如果项目全链路都用Newtonsoft.Json做序列化,不想修改现有实体类上的特性,可以给EventGrid客户端注入自定义序列化器,让它用Newtonsoft的规则处理payload:

  1. 先实现SDK提供的ObjectSerializer抽象类,封装Newtonsoft的序列化逻辑:
using Azure.Core.Serialization;
using Newtonsoft.Json;

public class NewtonsoftJsonEventGridSerializer : ObjectSerializer
{
    private readonly JsonSerializerSettings _jsonSettings;

    public NewtonsoftJsonEventGridSerializer(JsonSerializerSettings settings = null)
    {
        _jsonSettings = settings ?? new JsonSerializerSettings();
    }

    public override object Deserialize(Stream stream, Type returnType, CancellationToken cancellationToken)
    {
        using var streamReader = new StreamReader(stream);
        using var jsonReader = new JsonTextReader(streamReader);
        return JsonSerializer.Create(_jsonSettings).Deserialize(jsonReader, returnType);
    }

    public override async ValueTask<object> DeserializeAsync(Stream stream, Type returnType, CancellationToken cancellationToken)
    {
        using var streamReader = new StreamReader(stream);
        using var jsonReader = new JsonTextReader(streamReader);
        return await Task.FromResult(JsonSerializer.Create(_jsonSettings).Deserialize(jsonReader, returnType));
    }

    public override void Serialize(Stream stream, object value, Type inputType, CancellationToken cancellationToken)
    {
        using var streamWriter = new StreamWriter(stream, leaveOpen: true);
        using var jsonWriter = new JsonTextWriter(streamWriter);
        JsonSerializer.Create(_jsonSettings).Serialize(jsonWriter, value, inputType);
        jsonWriter.Flush();
    }

    public override async ValueTask SerializeAsync(Stream stream, object value, Type inputType, CancellationToken cancellationToken)
    {
        using var streamWriter = new StreamWriter(stream, leaveOpen: true);
        using var jsonWriter = new JsonTextWriter(streamWriter);
        JsonSerializer.Create(_jsonSettings).Serialize(jsonWriter, value, inputType);
        await jsonWriter.FlushAsync(cancellationToken);
    }
}
  1. 初始化EventGridPublisherClient时,传入配置了自定义序列化器的客户端选项:
var clientOptions = new EventGridPublisherClientOptions
{
    Serializer = new NewtonsoftJsonEventGridSerializer(new JsonSerializerSettings
    {
        // 这里可以放项目全局的Newtonsoft配置,比如命名策略、自定义转换器等
        Converters = { new StringEnumConverter() }
    })
};
// 替换为你自己的EventGrid主题终结点、访问密钥
_client = new EventGridPublisherClient(
    new Uri(_configuration.TopicEndpoint), 
    new Azure.AzureKeyCredential(_configuration.TopicKey), 
    clientOptions
);

配置完成后,原来写在实体类上的所有Newtonsoft特性、全局序列化规则都会正常生效。

方案3:提前手动序列化payload(侵入性最低,适合少量发送场景)

如果不想改客户端配置,也不想修改实体类代码,可以在构造EventGrid事件前,先用Newtonsoft把payload序列化成符合要求的JSON,再转成JsonDocument传入,直接绕过SDK的默认序列化逻辑:

public async Task SendMsg(string eventType, string dataVersion, object payload) 
{
    // 按自定义的Newtonsoft规则序列化payload
    var serializedPayload = JsonConvert.SerializeObject(payload, new StringEnumConverter());
    // 解析为JsonDocument传入EventGridEvent
    using var jsonDoc = JsonDocument.Parse(serializedPayload);
    var gridEvent = new EventGridEvent("myevent", eventType, dataVersion, jsonDoc.RootElement)
    {
        Topic = _configuration.Topic
    };
    await _client.SendEventAsync(gridEvent);
}

额外提示:当前代码里把CancellationTypes枚举定义在CuData类内部,虽然不会直接导致序列化失效,但不符合C#类型定义的常规实践,容易引发其他引用、序列化场景下的异常,建议把枚举定义移到类外层的命名空间下。

内容的提问来源于stack exchange,提问作者Ole Albers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:31:09