[英]What is the best practice for receiving/handling json data in 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; }
}
我已经按照惯例在这里实现了这一点:
它有效,但是我可以看到两个主要问题:
我的问题:有没有一种方法可以反序列化 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 文件中包含可选字段,这些字段不存在于其他文件中,而不会破坏您的代码。
这能帮助您解决问题吗?
我相信最佳实践是使用类。
这是我在您的情况下使用类的论点:
dynamic
的(呃),但它认为您的代码应该依赖于一个类(一个 dto)而不是一个 json 字符串。 这个输入结构恰好存储在 json 中,但可能不是。 大多数单元测试应该接受一个对象,而不是一个字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.