使用JSON.net自动序列化JSON服务器响应

时间:2018-12-14 20:36:04

标签: c# json json.net

学习C#。我正在使用JSON.net来序列化和反序列化服务器的响应。

我的工作确实很小。例如,对于OAuth2,我需要发送凭据以获取access_token。我必须通过以下方式做到这一点:

// Serialize the JSON response for the access_token
public class AccessToken
{
    public string access_token { get; set; }
}

static async void GetCrmAccessToken(FormUrlEncodedContent content)
{
    try
    {
        // Send the x-www-form-urlencoded info to the OAuth2 end point
        HttpResponseMessage response = await Client.PostAsync("https://login.windows.net/42daf6bc-f7add741ac61/oauth2/token", content);
        // Get the body from the response
        var responseContent = await response.Content.ReadAsStringAsync();

        // Extract out the access token from the repsonse
        AccessToken responseBody = JsonConvert.DeserializeObject<AccessToken>(responseContent);

        if (responseBody.access_token != "")
        {
            // If there is an access token, take it and use it in
            // generating the query
            RequestCrmQuery(responseBody.access_token);
        }
        else
        {
            Console.WriteLine("Could not get the access token.");
        }

    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        throw;
    }
}

基本上必须为我想要从JSON中获得的密钥创建一个带有公共变量的类。

现在我有了访问令牌,查询的响应就大得多。

  1. 是否需要为要使用JSON响应的每个键创建一个公共变量? (有几十个)。
  2. 这可以自动序列化吗?如果可以,怎么办?
  3. 服务器响应中的某些键具有疯狂的名称,例如biz_status@OData.Community.Display.V1.FormattedValue。无法在C#中使用该名称创建变量。这项工作如何给我提供重要的钥匙之一?
  4. 我可以将变量称为别的什么,但在对应的JSON中明确说明密钥吗?

2 个答案:

答案 0 :(得分:2)

我是否必须为要使用JSON响应的每个键创建一个公共变量? (有几十个)。 仅定义您需要的内容。

这可以自动序列化吗?如果是这样,怎么办? 是的。查看此答案中的实施: Nested Lists and Automapper.Map

服务器响应中的某些键具有疯狂的名称,例如:biz_status@OData.Community.Display.V1.FormattedValue。无法在C#中使用该名称创建变量。鉴于这是我需要使用的重要钥匙之一,该如何工作?

创建如下属性:

[SuppressMessage("ReSharper", "InconsistentNaming")]
[SerializePropertyNamesAsCamelCase]
public class SearchResult
{
    [JsonProperty("title")]
    public string Title { get; set; }

    [JsonProperty("abstract")]
    public string[] Abstract { get; set; }

    [JsonProperty("dateIssued")]
    public DateTime? DateIssued { get; set; }

    [JsonProperty("@search.score")]
    public decimal Score { get; set; }

    [JsonProperty("@search.highlights")]
    public Highlights Highlights { get; set; }
}

我可以将变量称为别的什么,但在对应的JSON中明确说明密钥吗? 是的。请参阅上面的实现

答案 1 :(得分:2)

使用json的三种主要方法:

  1. 使用json.net的JObject(可在其中获取属性),使用JPath访问特定节点(类似于XPath)。好消息是您不需要创建类,但是序列化到对象的过程要慢一些。

  2. 反序列化为.net对象。您将需要为每个所需的属性创建结构。

  3. 反序列化为动态\ expando对象-这使您能够使用动态类型。也无需创建类。

关于您的问题:

  1. 上面已回答。如果使用反序列化作为对象,则需要创建所有要访问的属性。

  2. 有些客户端在后台执行序列化。我更喜欢使用本机客户端并自己进行反序列化。您总是可以快速创建自定义内容。

  3. 您可以在任何属性上方使用[JsonProperty("<name of json property")]属性。

    [JsonProperty("realNodeName")] public string MyCoolProperty {get;set;}

  4. 与(3)相同。