在C#中使用Newtonsoft反序列化JSON

时间:2015-10-05 07:29:21

标签: c# json json.net

我有以下JSON:

[
    {
        "name": "codeURL",
        "value": "abcd"
    },
    {
        "name": "authURL",
        "value": "fghi"
    }
]

我创建了以下对象:

public class ConfigUrlModel {
    [JsonProperty("name")]
    public abstract string name { get; set; }
    [JsonProperty("value")]
    public abstract string value { get; set; }
}

public class ConfigUrlsModel {
    [JsonProperty]
    public List<ConfigUrlModel> ConfigUrls { get; set; }
}

我使用以下行反序列化:

resultObject = Newtonsoft.Json.JsonConvert.DeserializeObject<ConfigUrlsModel>(resultString);
ConfigUrlsModel result = resultObject as ConfigUrlsModel;

我收到以下错误:

Exception JsonSerializationException with no inner exception: Cannot deserialize JSON array into type 'Microsoft.Xbox.Samples.Video.Services.Jtv.Models.ConfigUrl.ConfigUrlsModel'.
Exception JsonSerializationException with no inner exception: Cannot deserialize JSON array into type 'Microsoft.Xbox.Samples.Video.Services.Jtv.Models.ConfigUrl.ConfigUrlsModel'.
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureArrayContract(Type objectType, JsonContract contract)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contr   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureArrayContract(Type objectType, JsonContract contract)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contrNavigationService:OnNavigateToMessage PageSourceUri=/Microsoft.Xbox.Sample.UI;component/ErrorPrompt/ErrorPromptView.xaml

我做错了什么?我该如何解决这个问题?

2 个答案:

答案 0 :(得分:5)

JSON容器是一个数组,而不是一个对象,因此反序列化它:

var configUrls = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ConfigUrlModel>>(resultString);
var result = new ConfigUrlsModel { ConfigUrls = configUrls }; // If you still need the root object.

JSON数组是值{{​​1}}的有序列表,这是您的问题中显示的内容。 Json.NET will convert .NET arrays and collections to JSON arrays,因此您需要反序列化为集合类型。

答案 1 :(得分:2)

您发送的JSON是一个数组,但您正在尝试将其反序列化为对象。以太改变您的JSON,使其与顶层的对象定义匹配,并具有匹配的属性,如下所示:

<PayPalPaymentDelegate, PayPalFuturePaymentDelegate>

或者将您的反序列化调用更改为:

#pragma mark - paypal

- (void)configPaypalPayment {

  _environment = PayPalEnvironmentSandbox;

  [PayPalMobile preconnectWithEnvironment:_environment];

  // Set up payPalConfig

  _payPalConfig = [[PayPalConfiguration alloc] init];
  _payPalConfig.acceptCreditCards = YES;
  _payPalConfig.merchantName = @"Andmine";
_payPalConfig.merchantPrivacyPolicyURL = [NSURL URLWithString:@"https://www.paypal.com/webapps/mpp/ua/privacy-full&#8221"];
    _payPalConfig.merchantUserAgreementURL = [NSURL URLWithString:@"https://www.paypal.com/webapps/mpp/ua/useragreement-full&#8221"];
   _payPalConfig.languageOrLocale = [NSLocale preferredLanguages][0];
   _payPalConfig.payPalShippingAddressOption = PayPalShippingAddressOptionNone;
}

#pragma mark -
#pragma mark PayPalPaymentDelegate methods

- (void)payPalPaymentViewController:
            (PayPalPaymentViewController *)paymentViewController
                 didCompletePayment:(PayPalPayment *)completedPayment {
  NSLog(@"PayPal Payment Success!");

  [self sendCompletedPaymentToServer:completedPayment]; // Payment was processed
                                                        // successfully; send to
                                                        // server for
                                                        // verification and
                                                        // fulfillment
  [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)payPalPaymentDidCancel:
    (PayPalPaymentViewController *)paymentViewController {
  NSLog(@"PayPal Payment Canceled");
  //  self.resultText = nil;
  //  self.successView.hidden = YES;
  [self dismissViewControllerAnimated:YES completion:nil];
}

#pragma mark Proof of payment validation

- (void)sendCompletedPaymentToServer:(PayPalPayment *)completedPayment {
  // TODO: Send completedPayment.confirmation to server
  NSLog(@"Here is your proof of payment:\n\n%@\n\nSend this to your server for "
        @"confirmation and fulfillment.",
        completedPayment.confirmation);
}

#pragma mark - Authorize Future Payments

- (IBAction)getUserAuthorizationForFuturePayments:(id)sender {

  PayPalFuturePaymentViewController *futurePaymentViewController =
      [[PayPalFuturePaymentViewController alloc]
          initWithConfiguration:self.payPalConfig
                       delegate:self];
  [self presentViewController:futurePaymentViewController
                     animated:YES
                   completion:nil];
}

#pragma mark PayPalFuturePaymentDelegate methods

- (void)payPalFuturePaymentViewController:
            (PayPalFuturePaymentViewController *)futurePaymentViewController
                didAuthorizeFuturePayment:
                    (NSDictionary *)futurePaymentAuthorization {
  NSLog(@"PayPal Future Payment Authorization Success!");
//  self.resultText = [futurePaymentAuthorization description];
//  [self showSuccess];

  [self sendFuturePaymentAuthorizationToServer:futurePaymentAuthorization];
  [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)payPalFuturePaymentDidCancel:
    (PayPalFuturePaymentViewController *)futurePaymentViewController {
  NSLog(@"PayPal Future Payment Authorization Canceled");
//  self.successView.hidden = YES;
  [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)sendFuturePaymentAuthorizationToServer:(NSDictionary *)authorization {
  // TODO: Send authorization to server
  NSLog(@"Here is your authorization:\n\n%@\n\nSend this to your server to "
        @"complete future payment setup.",
        authorization);
}

这将返回{ "ConfigUrls":[ { "name":"codeURL", "value":"abcd" }, { "name":"authURL", "value":"fghi" } ] } ,您可以直接使用它,也可以根据需要包装var urls = DeserializeObject<List<ConfigUrlModel>>(json); 实例。

此外,通过创建custom newtonsoft JsonConverter sublcass,可以将此JSON直接反序列化到所需的类。但这会使代码变得不那么清晰,所以尽可能避免使用它。