C# 解析有时是数组的json字符串
我正在尝试解析以下json: 正如您在列表元素的第一项中所看到的,描述是一个常规字符串。对于其他8个结果也是如此,但在第9个结果中,由于某种原因,它会变成字符串数组 我正在使用C#和一个DataContract来解析它,但它显然不起作用,因为结果之间的类型不同。 我怎样才能解决这个问题?我想可以手动解析所有内容,但我不想这样做 这是我的数据合同C# 解析有时是数组的json字符串,c#,json,parsing,datacontract,C#,Json,Parsing,Datacontract,我正在尝试解析以下json: 正如您在列表元素的第一项中所看到的,描述是一个常规字符串。对于其他8个结果也是如此,但在第9个结果中,由于某种原因,它会变成字符串数组 我正在使用C#和一个DataContract来解析它,但它显然不起作用,因为结果之间的类型不同。 我怎样才能解决这个问题?我想可以手动解析所有内容,但我不想这样做 这是我的数据合同 [DataContract] public class SwepubHeader { [DataMember(Name = "xsearch")
[DataContract]
public class SwepubHeader
{
[DataMember(Name = "xsearch")]
public SwepubBody Body { get; set; }
}
[DataContract]
public class SwepubBody
{
[DataMember(Name = "from")]
public int From { get; set; }
[DataMember(Name = "to")]
public int To { get; set; }
[DataMember(Name = "records")]
public int Records { get; set; }
[DataMember(Name = "list")]
public SwepubSearchItem[] SearchItems { get; set; }
}
[DataContract]
public class SwepubSearchItem
{
[DataMember(Name = "isbn")]
public string ISBN { get; set; }
[DataMember(Name = "title")]
public string Title { get; set; }
[DataMember(Name = "description")]
public string Description { get; set; }
[DataMember(Name = "identifier")]
public string Identifier { get; set; }
[DataMember(Name = "type")]
public string Type { get; set; }
[DataMember(Name = "publisher")]
public string Publisher { get; set; }
[DataMember(Name = "date")]
public string Date { get; set; }
[DataMember(Name = "language")]
public string Language { get; set; }
[DataMember(Name = "relation")]
public string Relation { get; set; }
[DataMember(Name = "subject")]
public string[] Subjects { get; set; }
[DataMember(Name = "creator")]
public string[] Creators { get; set; }
}
这就是我解析它的方式
using (var response = request.GetResponse() as HttpWebResponse)
{
if (response != null)
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(String.Format(
"Server error (HTTP {0}: {1}).",
response.StatusCode,
response.StatusDescription));
var jsonSerializer = new DataContractJsonSerializer(typeof(SwepubHeader));
object objResponse = jsonSerializer.ReadObject(response.GetResponseStream());
var jsonResponse = objResponse as SwepubHeader;
return jsonResponse;
}
}
url返回两个不同的JSON对象。就他们而言,这确实不是一个很好的设计,但是如果您无法控制它,那么一个选项是尝试使用字符串数据对其进行反序列化,如果失败,则使用字符串数组对其进行反序列化 编辑:为了使这项工作更容易,您应该将描述反序列化到对象。但是它不是字符串数组。。。它不是一个字符串就是一个对象数组。。。所以下面的代码将处理这个。。。将“描述”属性替换为以下内容
[DataMember(Name = "description")]
public object description { get; set; }
public string Description {
get
{
var seperator = string.Empty; // replace with what you want
var s = description as string;
if (s != null)
return s;
var sArray = description as object[];
if (sArray != null)
return String.Join(seperator, sArray);
return null;
}
set
{
description = value;
}
}
url返回两个不同的JSON对象。就他们而言,这确实不是一个很好的设计,但是如果您无法控制它,那么一个选项是尝试使用字符串数据对其进行反序列化,如果失败,则使用字符串数组对其进行反序列化 编辑:为了使这项工作更容易,您应该将描述反序列化到对象。但是它不是字符串数组。。。它不是一个字符串就是一个对象数组。。。所以下面的代码将处理这个。。。将“描述”属性替换为以下内容
[DataMember(Name = "description")]
public object description { get; set; }
public string Description {
get
{
var seperator = string.Empty; // replace with what you want
var s = description as string;
if (s != null)
return s;
var sArray = description as object[];
if (sArray != null)
return String.Join(seperator, sArray);
return null;
}
set
{
description = value;
}
}
对于他们的JSON格式来说,这确实不是一个很好的设计,但是您可以通过将描述作为一个对象来处理它。然后,如何处理该对象取决于您,但您可以创建另一个属性,将其转换为您需要的:
[DataMember(Name = "description"]
private object _description;
public string Description
{
get
{
if (_description != null)
{
if (_description is string)
{
// Do Nothing
// You can remove this, just putting this here to
// show conditional is implicit
}
else if (_description is string[])
{
// Join string[] using '\n\n' as the connector
_description = string.Join("\n\n", (string[])_description);
}
}
return _description as string;
}
}
对于他们的JSON格式来说,这确实不是一个很好的设计,但是您可以通过将描述作为一个对象来处理它。然后,如何处理该对象取决于您,但您可以创建另一个属性,将其转换为您需要的:
[DataMember(Name = "description"]
private object _description;
public string Description
{
get
{
if (_description != null)
{
if (_description is string)
{
// Do Nothing
// You can remove this, just putting this here to
// show conditional is implicit
}
else if (_description is string[])
{
// Join string[] using '\n\n' as the connector
_description = string.Join("\n\n", (string[])_description);
}
}
return _description as string;
}
}
如果他们给了你不同的数据类型,那么他们做错了什么,你应该告诉他们。他们应为其记录提供一致的类型。为了避免手动解析,您可以只定义两个类似的类型(都来自同一个基)-一个使用字符串,一个使用字符串数组-您可以尝试/捕获序列化为一个,然后是另一个。这两个类都可以实现类似于
GetDescription()
的功能,用于读取字符串或连接字符串数组。可能会有所帮助:我将使用Json.Net而不是DataContractJsonSerializer。它的反序列化速度几乎是原来的两倍,并且具有更多的特性。例如,您可以创建一个JsonConverter,它将接受该值,并让您确定该值的反序列化方式。如果他们给您提供了不同的数据类型,那么他们做错了什么,您应该告诉他们。他们应为其记录提供一致的类型。为了避免手动解析,您可以只定义两个类似的类型(都来自同一个基)-一个使用字符串,一个使用字符串数组-您可以尝试/捕获序列化为一个,然后是另一个。这两个类都可以实现类似于GetDescription()
的功能,用于读取字符串或连接字符串数组。可能会有所帮助:我将使用Json.Net而不是DataContractJsonSerializer。它的反序列化速度几乎是原来的两倍,并且具有更多的特性。例如,您可以创建一个JsonConverter,它将接受该值,并让您确定如何对其进行反序列化。谢谢,我甚至没有想过将该类型设为对象!谢谢你,我甚至没有想过把这个类型变成一个对象!我同意,这是一个糟糕的设计,但它不是我的,我不能让他们改变它。谢谢你的回答,我甚至没想过要把它做成一件物品!我同意,这是一个糟糕的设计,但它不是我的,我不能让他们改变它。谢谢你的回答,我甚至没想过要把它做成一件物品!