【问题标题】:ServiceStack - Dynamic/Object in DTOServiceStack - DTO 中的动态/对象
【发布时间】:2016-12-07 21:09:57
【问题描述】:

我在查看 SS 时遇到了问题。

我正在编写一个自定义的 Stripe 实现,但卡在了网络钩子上,尤其是: https://stripe.com/docs/api#event_object

data->object - 这可以是任何东西。

这是我的 DTO:

public class StripeEvent
{
    public string id { get; set; }

    public StripeEventData data { get; set; }

    public string type { get; set; }
}

[DataContract]
public class StripeEventData
{
    [DataMember(Name = "object")]
    public object _object { get; set; }
}

我希望基本上只是将该对象作为字符串获取,然后对其进行解析:

var invoice = (StripeInvoice)JsonSerializer.DeserializeFromString<StripeInvoice>(request.data._object.ToString());

不幸的是,从 ToString 返回的数据在每个 json 属性的名称周围都没有引号:

Capture

因此,DeserializeFromString 返回一个对象,该对象所有内容都为空。

为什么 SS 在内部去掉引号?这是处理可以是许多不同类型之一的 json 成员的正确方法吗?我确实尝试了动态的东西,但也没有任何运气 - 基本上与缺少引号的结果相同。

我非常彻底地搜索了 DTO 中对象和动态的使用,但对于这个问题确实没有任何帮助。

谢谢!

【问题讨论】:

  • 我无法重现您的问题。 request.data._object.ToString() 对我来说是一个合适的 JSON 对象。除此之外,这不是一个好方法。您应该检查object的实际类型并将其反序列化为一流的模型。
  • 关于如何做到这一点的任何建议? StripeEvent 中的“type”值表明了这一点,我打算做一个 switch 语句将 json 字符串解析到相应的类中。
  • 当然;处理invoice.updated 事件类型的任何人都应该知道object 属性是Invoice
  • 问题是我无法将它序列化到 Invoice 类中。由于报价已经消失,这是不可能的。在这里使用“对象”合适吗?有动态,但这没有帮助。我似乎错过了什么..
  • 不,接收事件的东西应该看到事件类型是invoice.updated,然后知道将data.object反序列化为Invoice。在您知道它是什么类型之前,您不应该反序列化 object.data;所以基本上,你想分两步反序列化:首先是顶级事件对象知道事件是什么类型(忽略它的嵌套数据),然后是嵌套数据以获取正确键入的内容。

标签: servicestack servicestack-text


【解决方案1】:

问题是您should never have an object type in DTOs 作为序列化程序不知道要反序列化回什么具体类型。

Stripe 文档说 object is a hash 您应该能够使用字典来捕获它,例如:

public class StripeEventData
{
    public Dictionary<string,string> @object { get; set; }
}

或者作为替代方案,您可以使用JsonObject,它提供了一个灵活的 API 来访问动态数据。

这适用于平面对象结构,但对于复杂的嵌套对象结构,您需要创建自定义类型 DTO,例如:

public class StripeEventInvoice
{
    public string id { get; set; }    
    public StripeEventDataInvoice data { get; set; }
    public string type { get; set; }
}

public class StripeEventData
{
    public StripeInvoice @object { get; set; }
}

【讨论】:

  • 谢谢!将字典或 JsonObject 转换为 StripeInvoice 的最佳方法是什么?
  • JsonObject 是 Dictionary 的替代品,而不是整个 StripeInvoice
  • 我明白这一点,但最好是填充类而不是字典/JsonObject。有没有一种好方法可以将其中任何一个转换为我的 dto 类(StripeInvoice)?
  • @DannyHuyn 如果有效负载与 StripeInvoice 模式匹配,您可以使用 jsonObject.ConvertTo&lt;StripeInvoice&gt;()
  • 谢谢 - 几乎完成了!这完成了所有顶级内容,如“id”和“close”,但更深层的内容,如 StripeInvoice 中的“行”,不会被填充。如果我将 StripeEventData 的“对象”属性设为 StripeInvoice 而不是 JsonObject,它会被填充,因此在这种情况下,ConvertTo 似乎无法完全工作。我错过了什么吗? Pastebin 供参考:pastebin.com/raw/AUbaeGJg
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-02
相关资源
最近更新 更多