Де сериализация объекта дает ошибку: Не удается десериализовать текущий объект JSON? - PullRequest
0 голосов
/ 24 октября 2018

Я звоню в отдел продаж, чтобы получить результат поиска.Для подключения к отделу продаж я использую Force Client.

var client = GetForceClient(token);
                string query = "FIND {01} IN ALL FIELDS RETURNING CASE(Id,Account.Name,Case_Id__c,Customer_Ticket_Id__c,Site__r.Name,Order__r.Name,Site__r.Country__c,Status,Subject LIMIT 5 OFFSET 0),Order__c(Order_Name__c,Tech_Service_Type__C,Customer__r.Name,End_Customer__r.Name,Site__r.Site_Name__c,name LIMIT 5 OFFSET 0),SITE__C(ID,Status__c,Address__c,Site_Name__c,NAME)";
                var response = await client.SearchAsync<Search>(query);

при десериализации результата в этой строке

 var response = await client.SearchAsync<Search>(query);

Выдается следующая ошибка.

   Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[API.Dto.Search]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
    To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
    Path 'searchRecords', line 1, position 17.

Ответ json выглядит следующим образом

{
  "searchRecords" : [ {
    "attributes" : {
      "type" : "Case",
      "url" : "/services/data/v43.0/sobjects/Case/5000D"
    },
    "Id" : "5000D",
    "Account" : {
      "attributes" : {
        "type" : "Account",
        "url" : "/services/data/v43.0/sobjects/Account/0010"
      },
      "Name" : "AAPTxxvvbb"
    },
    "Case_Id__c" : "CLIC-0001234",
    "Customer_Ticket_Id__c" : "33FWQ23",
    "Site__r" : null,
    "Order__r" : {
      "attributes" : {
        "type" : "Order__c",
        "url" : "/services/data/v43.0/sobjects/Order__c/a060D"
      },
      "Name" : "ORD-602"
    },
    "Status" : "Open",
    "Subject" : "Please Provide  Your Reference"
  }, {
    "attributes" : {
      "type" : "Order__c",
      "url" : "/services/data/v43.0/sobjects/Order__c/a060D"
    },
    "Order_Name__c" : "Bro 2K",
    "Tech_Service_Type__c" : "Bro",
    "Customer__r" : {
      "attributes" : {
        "type" : "Account",
        "url" : "/services/data/v43.0/sobjects/Account/0010"
      },
      "Name" : "XT"
    },
    "End_Customer__r" : {
      "attributes" : {
        "type" : "Account",
        "url" : "/services/data/v43.0/sobjects/Account/0010"
      },
      "Name" : "Ran"
    },
    "Site__r" : {
      "attributes" : {
        "type" : "Site__c",
        "url" : "/services/data/v43.0/sobjects/Site__c/a0A0"
      },
      "Site_Name__c" : "Ran01"
    },
    "Name" : "ORD-6025"
  }, {
    "attributes" : {
      "type" : "Site__c",
      "url" : "/services/data/v43.0/sobjects/Site__c/a0A0"
    },
    "Id" : "a0A0",
    "Status__c" : "In Progress",
    "Address__c" : "Rue",
    "Site_Name__c" : "Ran01",
    "Name" : "SIT-0154"
  } ]
}

Эквивалентный класс C # такой:

public class Search
    {
        [JsonProperty("searchRecords")]
        public SearchRecord[] SearchRecords { get; set; }
    }
    public class SearchRecord
    {
        [JsonProperty("attributes")]
        public Attributes Attributes { get; set; }

        [JsonProperty("Id", NullValueHandling = NullValueHandling.Ignore)]
        public string Id { get; set; }

        [JsonProperty("Account", NullValueHandling = NullValueHandling.Ignore)]
        public Account Account { get; set; }

        [JsonProperty("Case_Id__c", NullValueHandling = NullValueHandling.Ignore)]
        public string CaseIdC { get; set; }

        [JsonProperty("Customer_Ticket_Id__c", NullValueHandling = NullValueHandling.Ignore)]
        public string CustomerTicketIdC { get; set; }

        [JsonProperty("Site__r", NullValueHandling = NullValueHandling.Ignore)]
        public SiteR SiteR { get; set; }

        [JsonProperty("Order__r", NullValueHandling = NullValueHandling.Ignore)]
        public Account OrderR { get; set; }

        [JsonProperty("Status", NullValueHandling = NullValueHandling.Ignore)]
        public string Status { get; set; }

        [JsonProperty("Subject", NullValueHandling = NullValueHandling.Ignore)]
        public string Subject { get; set; }

        [JsonProperty("Order_Name__c", NullValueHandling = NullValueHandling.Ignore)]
        public string OrderNameC { get; set; }

        [JsonProperty("Tech_Service_Type__c", NullValueHandling = NullValueHandling.Ignore)]
        public string TechServiceTypeC { get; set; }

        [JsonProperty("Customer__r", NullValueHandling = NullValueHandling.Ignore)]
        public Account CustomerR { get; set; }

        [JsonProperty("End_Customer__r", NullValueHandling = NullValueHandling.Ignore)]
        public Account EndCustomerR { get; set; }

        [JsonProperty("Name", NullValueHandling = NullValueHandling.Ignore)]
        public string Name { get; set; }

        [JsonProperty("Status__c")]
        public object StatusC { get; set; }

        [JsonProperty("Address__c")]
        public string AddressC { get; set; }

        [JsonProperty("Site_Name__c", NullValueHandling = NullValueHandling.Ignore)]
        public string SiteNameC { get; set; }
    }

    public partial class Attributes
    {
        [JsonProperty("type")]
        public string Type { get; set; }

        [JsonProperty("url")]
        public string Url { get; set; }
    }

Я много искал это, но не смог выяснить, чтонеправильно.

1 Ответ

0 голосов
/ 25 октября 2018

Проблема вызвана тем, как метод SearchAsync в ForceClient десериализует ответ.

Клиент пытается десериализовать ответ от сервера как List<T>, но, как мы видим вJSON, ответ сначала оборачивается в элемент searchRecords, поэтому десериализация создает исключение, которое вы видите.

Чтобы обойти это, вам нужно сделать следующее:

Изменить SearchAsync вызов для использования типа dynamic:

var response = await client.SearchAsync<dynamic>(query);

Десериализация свойства searchRecords нового типа в массив SearchRecord

var records = JsonConvert.DeserializeObject<List<SearchRecord>>(list.searchRecords.ToString());

Теперь вы можете использоватьпеременная records для чтения данных, возвращаемых из вызова API.

NOTE Для справки я посмотрел на источник на GitHub и обнаружил, как * 1028Метод * SearchAsync сработал, а затем посмотрел на тесты, чтобы выяснить, как они извлекают данные из вызова SearchAsync.Код модульного теста, который показал мне ответ: здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...