ServiceStack如何局部映射带连字符请求属性(Mailgun event-data)
问题说明
对接Mailgun webhook时,平台传递的事件字段名为event-data,需要在不修改ServiceStack全局序列化配置(避免影响现有CMS系统功能)的前提下,仅针对/mailgun/webhook路由的POST请求实现字段映射。
解决方案
不需要调整全局JsConfig,采用属性级标注的方式即可实现单字段映射,配置仅作用于当前DTO,不会对系统其他模块的序列化逻辑产生影响。
方案1:属性别名标注(推荐)
ServiceStack原生支持DataMember特性指定属性对应的序列化/反序列化字段名,作用范围仅限标注的单个属性。
注意:你当前定义的
EventData类型与Mailgun实际传递的结构不匹配:实际传递的是单个JSON对象而非数组,且包含数值类型的时间戳字段,不是全字符串键值对集合。
修正后的DTO定义如下:
using System.Runtime.Serialization; using ServiceStack; [Route("/mailgun/webhook")] public class MailgunWebhookListenerRequest : IReturn<string> { public MailgunWebhookSignature Signature { get; set; } // 指定当前属性映射JSON中的event-data字段 [DataMember(Name = "event-data")] public MailgunWebhookEventData EventData { get; set; } } /// <summary> /// Mailgun webhook签名结构 /// </summary> public class MailgunWebhookSignature { public string Timestamp { get; set; } public string Token { get; set; } public string Signature { get; set; } } /// <summary> /// Mailgun事件数据结构 /// </summary> public class MailgunWebhookEventData { public string Event { get; set; } public decimal Timestamp { get; set; } public string Id { get; set; } }
如果不需要强类型定义事件结构,可以将EventData类型改为Dictionary<string, object>接收动态结构:
[DataMember(Name = "event-data")] public Dictionary<string, object> EventData { get; set; }
方案2:自定义请求反序列化逻辑
如果需要更灵活的控制,可以直接读取原始请求体,针对当前请求使用独立的反序列化规则,完全不依赖默认的全局反序列化配置:
public class MailgunWebhookService : Service { public async Task<string> Post(MailgunWebhookListenerRequest requestDto) { // 读取原始请求JSON var rawJson = await Request.GetRawBodyAsync(); // 针对当前请求使用自定义反序列化规则,配置仅在当前作用域生效 var request = JsonSerializer.DeserializeFromString<MailgunWebhookListenerRequest>( rawJson, new JsonSerializerOptions { PropertyNameResolver = propName => propName == nameof(MailgunWebhookListenerRequest.EventData) ? "event-data" : propName.ToCamelCase() }); // 后续业务处理逻辑 return "success"; } }
内容的提问来源于stack exchange,提问作者Steve McNiven-Scott
相关产品推荐
相关产品推荐

