繁体   English   中英

在 c# 中接收/处理 json 数据的最佳实践是什么?

[英]What is the best practice for receiving/handling json data in c#?

C#

假设我想制作一个 winform 页面,该页面接收从 json 文件内容中读取的一定数量的随机特征。 (使用“Newtonsoft.Json”库时)

反序列化 json 文件的代码

 Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(File.ReadAllText(@"..\..\Json\features.json"));

这些类被设置为在同一个 c# 文件中表示 json 文件的内容和结构,但当然在主类之外。

class Root
{
    public List<Category> category { get; set; }
}

class Category
{
    public string name { get; set; }
    public List<Feature> feature { get; set; }
}

class Feature
{
    public string name { get; set; }
    public string frequency { get; set; }
}

我已经按照惯例在这里实现了这一点:

它有效,但是我可以看到两个主要问题:

  1. 它最终可能会使 .cs 文件在视觉上杂乱无章,其中包含许多您永远不需要查看或编辑的类,尤其是在它解释多个 json 文件时
  2. 它不是动态的,它仅适用于您必须通过为 json 文件中存在的每个子类创建这些类来使其兼容的一个 json 文件。

我的问题:有没有一种方法可以反序列化 json 文件,而不必为 json 字符串中的每个数据子类别创建多个类?

我相信你不需要这些类,因为你不需要整个 JSON 字符串,对吗?

如果是这样,您可以仅部分反序列化您感兴趣的部分,而不是反序列化整个 json 文件。

看一下 Newtonsoft.Json 文档中的这个例子,我们有一个长的 json 字符串表示来自 Google 搜索的响应,但只对它的responseData/results部分感兴趣,并且只对该结果对象的某些字段感兴趣:

部分反序列化的对象:

public class SearchResult
{
    public string Title { get; set; }
    public string Content { get; set; }
    public string Url { get; set; }
}

反序列化部分 JSON 片段示例:

string googleSearchText = @"{
  'responseData': {
    'results': [
      {
        'GsearchResultClass': 'GwebSearch',
        'unescapedUrl': 'http://en.wikipedia.org/wiki/Paris_Hilton',
        'url': 'http://en.wikipedia.org/wiki/Paris_Hilton',
        'visibleUrl': 'en.wikipedia.org',
        'cacheUrl': 'http://www.google.com/search?q=cache:TwrPfhd22hYJ:en.wikipedia.org',
        'title': '<b>Paris Hilton</b> - Wikipedia, the free encyclopedia',
        'titleNoFormatting': 'Paris Hilton - Wikipedia, the free encyclopedia',
        'content': '[1] In 2006, she released her debut album...'
      },
      {
        'GsearchResultClass': 'GwebSearch',
        'unescapedUrl': 'http://www.imdb.com/name/nm0385296/',
        'url': 'http://www.imdb.com/name/nm0385296/',
        'visibleUrl': 'www.imdb.com',
        'cacheUrl': 'http://www.google.com/search?q=cache:1i34KkqnsooJ:www.imdb.com',
        'title': '<b>Paris Hilton</b>',
        'titleNoFormatting': 'Paris Hilton',
        'content': 'Self: Zoolander. Socialite <b>Paris Hilton</b>...'
      }
    ],
    'cursor': {
      'pages': [
        {
          'start': '0',
          'label': 1
        },
        {
          'start': '4',
          'label': 2
        },
        {
          'start': '8',
          'label': 3
        },
        {
          'start': '12',
          'label': 4
        }
      ],
      'estimatedResultCount': '59600000',
      'currentPageIndex': 0,
      'moreResultsUrl': 'http://www.google.com/search?oe=utf8&ie=utf8...'
    }
  },
  'responseDetails': null,
  'responseStatus': 200
}";

// Parse JSON into a JObject, which we can easily traverse
JObject googleSearch = JObject.Parse(googleSearchText);

// get JSON result objects into a list
IList<JToken> results = googleSearch["responseData"]["results"].Children().ToList();

// serialize JSON results into .NET objects
IList<SearchResult> searchResults = new List<SearchResult>();
foreach (JToken result in results)
{
    // JToken.ToObject is a helper method that uses JsonSerializer internally
    SearchResult searchResult = result.ToObject<SearchResult>();
    searchResults.Add(searchResult);
}

// Title = <b>Paris Hilton</b> - Wikipedia, the free encyclopedia
// Content = [1] In 2006, she released her debut album...
// Url = http://en.wikipedia.org/wiki/Paris_Hilton

// Title = <b>Paris Hilton</b>
// Content = Self: Zoolander. Socialite <b>Paris Hilton</b>...
// Url = http://www.imdb.com/name/nm0385296/

这样,我们只需要为SearchResult创建一个类,不需要其他任何东西,这听起来像你想要的。 在使用googleSearch["responseData"]["results"]类的代码遍历 JSON 对象时,您可以检查结果是否为 null 并采取相应措施,这意味着您可以在 JSON 文件中包含可选字段,这些字段不存在于其他文件中,而不会破坏您的代码。

这能帮助您解决问题吗?

我相信最佳实践是使用类。

这是我在您的情况下使用类的论点:

  1. 您可以一点一点地读取 json,使用JObject.Parse甚至是dynamic的(呃),但它认为您的代码应该依赖于一个类(一个 dto)而不是一个 json 字符串。 这个输入结构恰好存储在 json 中,但可能不是。 大多数单元测试应该接受一个对象,而不是一个字符串。
  2. 我发现反序列化类的论点不是动态弱的,因为您需要编写将处理添加的元素的代码。 换句话说,如果您向 json 添加新功能,它不仅可以正常工作,您还需要编写代码来支持它,并且每次更改 json 结构时,无论如何您都需要更新代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM