代码之家  ›  专栏  ›  技术社区  ›  confusedMind

对条带JSON响应进行反序列化时出现问题

  •  0
  • confusedMind  · 技术社区  · 6 年前

    我已经创建了一个类来反序列化StripeJSON响应,它可以找到,但在某些情况下,我会得到错误:

    Cannot convert null to a value type.
    

    即使我能看到类型总是在最后。

    回答如下:

      {
      "id": "evt_1Dezu4HJCcuwD0sbvkmV6bEb",
      "object": "event",
      "api_version": "2018-11-08",
      "created": 1544252828,
      "data": {
        "object": {
          "id": "sub_E7ExxxXGawn6cu",
          "object": "subscription",
          "application_fee_percent": null,
          "billing": "charge_automatically",
          "billing_cycle_anchor": 1544252827,
          "cancel_at_period_end": false,
          "canceled_at": null,
          "created": 1544252827,
          "current_period_end": 1544339227,
          "current_period_start": 1544252827,
          "customer": "cus_E7xxxQqowY9",
          "days_until_due": null,
          "default_source": null,
          "discount": null,
          "ended_at": null,
          "items": {
            "object": "list",
            "data": [
              {
                "id": "si_E7EMDEdBnD6wUx",
                "object": "subscription_item",
                "created": 1544252828,
                "metadata": {
                },
                "plan": {
                  "id": "plan_E5lRIPvrkNuRBB",
                  "object": "plan",
                  "active": true,
                  "aggregate_usage": null,
                  "amount": 0,
                  "billing_scheme": "per_unit",
                  "created": 1543997153,
                  "currency": "usd",
                  "interval": "day",
                  "interval_count": 1,
                  "livemode": false,
                  "metadata": {
                  },
                  "nickname": "Free Plan",
                  "product": "prod_E1CBxxxpNa5Lf02d",
                  "tiers": null,
                  "tiers_mode": null,
                  "transform_usage": null,
                  "trial_period_days": null,
                  "usage_type": "licensed"
                },
                "quantity": 1,
                "subscription": "sub_E7xxxXGawn6cu"
              }
            ],
            "has_more": false,
            "total_count": 1,
            "url": "/v1/subscription_items?subscription=sub_E7xxxXGawn6cu"
          },
          "livemode": false,
          "metadata": {
          },
          "plan": {
            "id": "plan_E5lRIPxxxkNuRBB",
            "object": "plan",
            "active": true,
            "aggregate_usage": null,
            "amount": 0,
            "billing_scheme": "per_unit",
            "created": 1543997153,
            "currency": "usd",
            "interval": "day",
            "interval_count": 1,
            "livemode": false,
            "metadata": {
            },
            "nickname": "Free Plan",
            "product": "prod_E1CBZpNa5Lf02d",
            "tiers": null,
            "tiers_mode": null,
            "transform_usage": null,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "quantity": 1,
          "start": 1544252827,
          "status": "active",
          "tax_percent": null,
          "trial_end": null,
          "trial_start": null
        }
      },
      "livemode": false,
      "pending_webhooks": 1,
      "request": {
        "id": "req_OJV215KMm",
        "idempotency_key": null
      },
      "type": "customer.subscription.created"
    } 
    

    班级:

    public class WebHookObjec
    {
    
        public int created { get; set; }
        public bool livemode { get; set; }
        public string id { get; set; }
        public string @object { get; set; }
        public object request { get; set; }
        public string type { get; set; } 
        public int pending_webhooks { get; set; }
        public string api_version { get; set; }
        public Data data { get; set; }
    
        public class Metadata
        {
        }
    
    
        public class Plan
        {
            public string id { get; set; }
            public string @object { get; set; }
            public bool active { get; set; }
            public object aggregate_usage { get; set; }
            public int amount { get; set; }
            public string billing_scheme { get; set; }
            public int created { get; set; }
            public string currency { get; set; }
            public string interval { get; set; }
            public int interval_count { get; set; }
            public bool livemode { get; set; }
            public Metadata metadata { get; set; }
            public string nickname { get; set; }
            public string product { get; set; }
            public object tiers { get; set; }
            public object tiers_mode { get; set; }
            public object transform_usage { get; set; }
            public int trial_period_days { get; set; }
            public string usage_type { get; set; }
        }
    
        public class Phase
        {
            public object application_fee_percent { get; set; }
            public object coupon { get; set; }
            public int end_date { get; set; }
            public List<Plan> plans { get; set; }
            public int start_date { get; set; }
            public object tax_percent { get; set; }
            public bool trial { get; set; }
            public object trial_end { get; set; }
        }
        public class PreviousAttributes
        {
            public string status { get; set; }
        }
    
        public class Object
        {
            public string id { get; set; }
            public string @object { get; set; }
            public string billing { get; set; }
            public object canceled_at { get; set; }
            public object completed_at { get; set; }
            public int created { get; set; }
            public object current_phase { get; set; }
            public string customer { get; set; }
            public object invoice_settings { get; set; }
            public bool livemode { get; set; }
            public List<Phase> phases { get; set; }
            public object released_at { get; set; }
            public object released_subscription { get; set; }
            public string renewal_behavior { get; set; }
            public object renewal_interval { get; set; }
            public string revision { get; set; }
            public string status { get; set; }
            public object subscription { get; set; }
            public Plan plan { get; set; }
            public int quantity { get; set; }
            public int start { get; set; }
            public object tax_percent { get; set; }
            public int trial_end { get; set; }
            public int trial_start { get; set; }
    
            public int amount { get; set; }
            public int amount_refunded { get; set; }
            public object application { get; set; }
            public object application_fee { get; set; }
            public string balance_transaction { get; set; }
            public bool captured { get; set; }
            public string currency { get; set; }
            public string description { get; set; }
            public object destination { get; set; }
            public object dispute { get; set; }
            public object failure_code { get; set; }
            public object failure_message { get; set; }
            public FraudDetails fraud_details { get; set; }
            public object invoice { get; set; }
            public Metadata metadata { get; set; }
            public object on_behalf_of { get; set; }
            public object order { get; set; }
            public object outcome { get; set; }
            public bool paid { get; set; }
            public object payment_intent { get; set; }
            public object receipt_email { get; set; }
            public object receipt_number { get; set; }
            public bool refunded { get; set; }
            public Refunds refunds { get; set; }
            public object review { get; set; }
            public object shipping { get; set; }
            public Source source { get; set; }
            public object source_transfer { get; set; }
            public object statement_descriptor { get; set; }
            public object transfer_group { get; set; }
    
        }
    
        public class Data
        {
            public Object @object { get; set; }
            public PreviousAttributes previous_attributes { get; set; }
        }
    
        public class FraudDetails
        {
        }
    
    
        public class Refunds
        {
            public string @object { get; set; }
            public List<object> data { get; set; }
            public bool has_more { get; set; }
            public int total_count { get; set; }
            public string url { get; set; }
        }
    
        public class Metadata2
        {
        }
    
        public class Source
        {
            public string id { get; set; }
            public string @object { get; set; }
            public object address_city { get; set; }
            public object address_country { get; set; }
            public object address_line1 { get; set; }
            public object address_line1_check { get; set; }
            public object address_line2 { get; set; }
            public object address_state { get; set; }
            public object address_zip { get; set; }
            public object address_zip_check { get; set; }
            public string brand { get; set; }
            public string country { get; set; }
            public string customer { get; set; }
            public string cvc_check { get; set; }
            public object dynamic_last4 { get; set; }
            public int exp_month { get; set; }
            public int exp_year { get; set; }
            public string fingerprint { get; set; }
            public string funding { get; set; }
            public string last4 { get; set; }
            public Metadata2 metadata { get; set; }
            public string name { get; set; }
            public object tokenization_method { get; set; }
        }
    
    }
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   er-sho    6 年前

    在分析了JSON和JSON的类对象之后。

    JSON包含名为的属性 "trial_period_days": null, 已为空,并且您声明了其integer类型的各自属性 public int trial_period_days { get; set; } 在里面 Plan 类对象。

    所以 int 是值类型,不能强制转换为 null .

    要消除此异常,您需要将属性修改为以下任一项。

    public object trial_period_days { get; set; }
    

    public int? trial_period_days { get; set; }
    

    你的剩余财产也一样 Object 类用于 trial_start trial_end .

    注: 不要使用 对象 作为自定义类名,因为它已经在.NET框架中预定义了类。

        2
  •  0
  •   D-Shih    6 年前

    因为JSON数据中有一些属性是空的,但是您使用值类型来携带它。

    你可以试着用 string 键入以表示这些模型的空值属性,以便携带JSON数据。

      public class Metadata
    {
    }
    
    public class Metadata2
    {
    }
    
    public class Plan
    {
        public string id { get; set; }
        public string @string { get; set; }
        public bool active { get; set; }
        public string aggregate_usage { get; set; }
        public int amount { get; set; }
        public string billing_scheme { get; set; }
        public int created { get; set; }
        public string currency { get; set; }
        public string interval { get; set; }
        public int interval_count { get; set; }
        public bool livemode { get; set; }
        public Metadata2 metadata { get; set; }
        public string nickname { get; set; }
        public string product { get; set; }
        public string tiers { get; set; }
        public string tiers_mode { get; set; }
        public string transform_usage { get; set; }
        public string trial_period_days { get; set; }
        public string usage_type { get; set; }
    }
    
    public class Datum
    {
        public string id { get; set; }
        public string @string { get; set; }
        public int created { get; set; }
        public Metadata metadata { get; set; }
        public Plan plan { get; set; }
        public int quantity { get; set; }
        public string subscription { get; set; }
    }
    
    public class Items
    {
        public string @string { get; set; }
        public List<Datum> data { get; set; }
        public bool has_more { get; set; }
        public int total_count { get; set; }
        public string url { get; set; }
    }
    
    public class Metadata3
    {
    }
    
    public class Metadata4
    {
    }
    
    public class Plan2
    {
        public string id { get; set; }
        public string @string { get; set; }
        public bool active { get; set; }
        public string aggregate_usage { get; set; }
        public int amount { get; set; }
        public string billing_scheme { get; set; }
        public int created { get; set; }
        public string currency { get; set; }
        public string interval { get; set; }
        public int interval_count { get; set; }
        public bool livemode { get; set; }
        public Metadata4 metadata { get; set; }
        public string nickname { get; set; }
        public string product { get; set; }
        public string tiers { get; set; }
        public string tiers_mode { get; set; }
        public string transform_usage { get; set; }
        public string trial_period_days { get; set; }
        public string usage_type { get; set; }
    }
    
    public class content
    {
        public string id { get; set; }
        public string @string { get; set; }
        public string application_fee_percent { get; set; }
        public string billing { get; set; }
        public int billing_cycle_anchor { get; set; }
        public bool cancel_at_period_end { get; set; }
        public string canceled_at { get; set; }
        public int created { get; set; }
        public int current_period_end { get; set; }
        public int current_period_start { get; set; }
        public string customer { get; set; }
        public string days_until_due { get; set; }
        public string default_source { get; set; }
        public string discount { get; set; }
        public string ended_at { get; set; }
        public Items items { get; set; }
        public bool livemode { get; set; }
        public Metadata3 metadata { get; set; }
        public Plan2 plan { get; set; }
        public int quantity { get; set; }
        public int start { get; set; }
        public string status { get; set; }
        public string tax_percent { get; set; }
        public string trial_end { get; set; }
        public string trial_start { get; set; }
    }
    
    public class Data
    {
        public content @object { get; set; }
    }
    
    public class Request
    {
        public string id { get; set; }
        public string idempotency_key { get; set; }
    }
    
    public class RootObject
    {
        public string id { get; set; }
        public string @string { get; set; }
        public string api_version { get; set; }
        public int created { get; set; }
        public Data data { get; set; }
        public bool livemode { get; set; }
        public int pending_webhooks { get; set; }
        public Request request { get; set; }
        public string type { get; set; }
    }
    

    使用方法如下

    var result =JsonConvert.DeserializeObject<RootObject>(data);
    

    注意

    有两种方法可以轻松创建模型。

    • 您可以在Visual Studio中使用Web Essentials,使用edit>Paste Special>将JSON粘贴为类,您可以更容易地了解JSON和模型之间的关系。

    • 如果您不能使用Web Essentials,则可以使用 http://json2csharp.com/ 在线JSON到模型类。

    您可以尝试使用这些模型来携带JSON格式。