C# Webapi中应用程序/xml的序列化失败
我已更新了问题,请参见更新1下的 当我的WebAPI试图以XML格式返回数据时,我遇到了一个错误。JSON格式工作正常 错误详细信息: ObjectContent“1”类型未能序列化内容类型的响应正文 '应用程序/xml;字符集=utf-8 "C# Webapi中应用程序/xml的序列化失败,c#,json,xml,asp.net-web-api,json.net,C#,Json,Xml,Asp.net Web Api,Json.net,我已更新了问题,请参见更新1下的 当我的WebAPI试图以XML格式返回数据时,我遇到了一个错误。JSON格式工作正常 错误详细信息: ObjectContent“1”类型未能序列化内容类型的响应正文 '应用程序/xml;字符集=utf-8 " 详细错误:: 类型“Newtonsoft.Json.Linq.JToken”是不受支持的递归收集数据协定。考虑修改集合“NeNethSoop.JSO.LINQ,JToken”的定义,以删除对自身的引用。 不知怎的,我明白了这是由于从Json.Net发
- 详细错误::
return (JsonConvert.DeserializeObject(JsonString, new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
}));
这里的问题是,我不能再创建一个模型类,因为结果将基于用户字段选择(我已经在使用一个模型类)动态地发送结果给用户
我们希望同时支持XML和JSON格式,并且已经尝试了StackOverflow中提到的大多数解决方案。任何帮助都将不胜感激
更新1
我已尝试实施链接中提到的解决方案
但它仍然显示了相同的错误
为了确保我做了正确的事情,我在这里发布代码
我在这里得到这份工作
object test = JsonHandling.generateResultSet<IEnumerable<Mytype>>
(reader,"dsfw");
最终申报表:
PagedResults<MyType> result = new PagedResults<MyType>();
result = result.CreatePagedResults<MyType>(test, offset, limit,
Request, "jkewgfewg");
return Ok(result);
PagedResults结果=新的PagedResults();
结果=结果。CreatePagedResults(测试、偏移、限制、,
请求,“jkewgfewg”);
返回Ok(结果);
我已经添加了前面提到的JsonExtensions,原因是我们的答案不适用于您,因为您使用的是
DataContractSerializer
,而该答案适用于XmlSerializer
。您有几个选项可以解决此问题
首先,您可以按照说明全局切换到XmlSerializer
,或者按照说明切换到特定控制器,或者切换到所示或所示的特定响应
其次,您可以使用注释您的PagedResults
,以确保JObject
值属性未序列化:
[DataContract]
public class PagedResults<T>
{
/// <summary>
/// The page number this page represents.
/// </summary>
///
[DataMember]
public int? OffSet { get; set; }
/// <summary>
/// The size of this page.
/// </summary>
[DataMember]
public int? Limit { get; set; }
// /// <summary>
// /// The total number of pages available.
// /// </summary>
//// public int TotalNumberOfPages { get; set; }
/// <summary>
/// The total number of records available.
/// </summary>
[DataMember]
public int TotalNumberOfRecords { get; set; }
/// <summary>
/// The URL to the next page - if null, there are no more pages.
/// </summary>
[DataMember]
public string NextPageUrl { get; set; }
/// <summary>
/// The URL to the Previous page - if null, there are no more pages.
/// </summary>
[DataMember]
public string PrevPageUrl { get; set; }
/// <summary>
/// The URL to the Current page page - if null, there are no more pages.
/// </summary>
[DataMember]
public string CurrentPageUrl { get; set; }
/// <summary>
/// The records this page represents.
/// </summary>
[XmlIgnore]
[IgnoreDataMember]
[JsonProperty]
public object Results { get; set; }
[XmlAnyElement("Results")]
[DataMember(Name = "Results")]
[JsonIgnore]
public XElement ResultsXml
{
get
{
return JsonExtensions.SerializeExtraDataXElement("Results", Results);
}
set
{
Results = JsonExtensions.DeserializeExtraDataXElement("Results", value);
}
}
}
使用每个序列化程序序列化一个PagedResult
,会得到以下结果:
- Json.NET:
{ "OffSet": 0, "Limit": 1000, "TotalNumberOfRecords": 1000, "NextPageUrl": "next link", "PrevPageUrl": "prev link", "CurrentPageUrl": "curr link", "Results": { "Foo": "Foo Value", "Bar": "Bar Value" } }
:XmlSerializer
<PagedResultsOfMyType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <OffSet>0</OffSet> <Limit>1000</Limit> <TotalNumberOfRecords>1000</TotalNumberOfRecords> <NextPageUrl>next link</NextPageUrl> <PrevPageUrl>prev link</PrevPageUrl> <CurrentPageUrl>curr link</CurrentPageUrl> <Results> <Foo>Foo Value</Foo> <Bar>Bar Value</Bar> </Results> </PagedResultsOfMyType>
<PagedResultsOfMyType5vmUPXwL xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Question45426622"> <CurrentPageUrl>curr link</CurrentPageUrl> <Limit>1000</Limit> <NextPageUrl>next link</NextPageUrl> <OffSet>0</OffSet> <PrevPageUrl>prev link</PrevPageUrl> <Results> <!--Notice the nested extra <Results> node below --> <Results xmlns=""> <Foo>Foo Value</Foo> <Bar>Bar Value</Bar> </Results> </Results> <TotalNumberOfRecords>1000</TotalNumberOfRecords> </PagedResultsOfMyType5vmUPXwL>
注意到嵌套的、添加的
节点级别了吗?使用DataContractSerializer
无法避免这种情况,除非您为整个PagedResult
对象手动实现IXmlSerializer
,我不建议这样做,因为它很难正确执行。的答案不适用于您,因为您使用的是DataContractSerializer
,而该答案适用于XmlSerializer
。您有几个选项可以解决此问题
首先,您可以按照说明全局切换到XmlSerializer
,或者按照说明切换到特定控制器,或者切换到所示或所示的特定响应
其次,您可以使用注释您的PagedResults
,以确保JObject
值属性未序列化:
[DataContract]
public class PagedResults<T>
{
/// <summary>
/// The page number this page represents.
/// </summary>
///
[DataMember]
public int? OffSet { get; set; }
/// <summary>
/// The size of this page.
/// </summary>
[DataMember]
public int? Limit { get; set; }
// /// <summary>
// /// The total number of pages available.
// /// </summary>
//// public int TotalNumberOfPages { get; set; }
/// <summary>
/// The total number of records available.
/// </summary>
[DataMember]
public int TotalNumberOfRecords { get; set; }
/// <summary>
/// The URL to the next page - if null, there are no more pages.
/// </summary>
[DataMember]
public string NextPageUrl { get; set; }
/// <summary>
/// The URL to the Previous page - if null, there are no more pages.
/// </summary>
[DataMember]
public string PrevPageUrl { get; set; }
/// <summary>
/// The URL to the Current page page - if null, there are no more pages.
/// </summary>
[DataMember]
public string CurrentPageUrl { get; set; }
/// <summary>
/// The records this page represents.
/// </summary>
[XmlIgnore]
[IgnoreDataMember]
[JsonProperty]
public object Results { get; set; }
[XmlAnyElement("Results")]
[DataMember(Name = "Results")]
[JsonIgnore]
public XElement ResultsXml
{
get
{
return JsonExtensions.SerializeExtraDataXElement("Results", Results);
}
set
{
Results = JsonExtensions.DeserializeExtraDataXElement("Results", value);
}
}
}
使用每个序列化程序序列化一个PagedResult
,会得到以下结果:
- Json.NET:
{ "OffSet": 0, "Limit": 1000, "TotalNumberOfRecords": 1000, "NextPageUrl": "next link", "PrevPageUrl": "prev link", "CurrentPageUrl": "curr link", "Results": { "Foo": "Foo Value", "Bar": "Bar Value" } }
:XmlSerializer
<PagedResultsOfMyType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <OffSet>0</OffSet> <Limit>1000</Limit> <TotalNumberOfRecords>1000</TotalNumberOfRecords> <NextPageUrl>next link</NextPageUrl> <PrevPageUrl>prev link</PrevPageUrl> <CurrentPageUrl>curr link</CurrentPageUrl> <Results> <Foo>Foo Value</Foo> <Bar>Bar Value</Bar> </Results> </PagedResultsOfMyType>
<PagedResultsOfMyType5vmUPXwL xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Question45426622"> <CurrentPageUrl>curr link</CurrentPageUrl> <Limit>1000</Limit> <NextPageUrl>next link</NextPageUrl> <OffSet>0</OffSet> <PrevPageUrl>prev link</PrevPageUrl> <Results> <!--Notice the nested extra <Results> node below --> <Results xmlns=""> <Foo>Foo Value</Foo> <Bar>Bar Value</Bar> </Results> </Results> <TotalNumberOfRecords>1000</TotalNumberOfRecords> </PagedResultsOfMyType5vmUPXwL>
注意到嵌套的、添加的
节点级别了吗?使用DataContractSerializer
无法避免这一点,除非您为整个PagedResult
对象手动实现IXmlSerializer
,我不建议这样做,因为它很难正确执行。错误消息来自newtonsoft.json,但您的投诉是xml格式不正确?这对我来说似乎是不匹配的;您使用的是json还是xml?您的查询是否缺少一些可以帮助我们解决问题的细节?您首先从哪里获取Json字符串?@BrianRogers:我从我的模型对象获取Json字符串。使用Newtonsoft的原因是忽略包含null的列。字符串JsonString=JsonConvert.SerializeObject(结果列表,新JsonSerializerSettings{//Formatting=Formatting.Indented,NullValueHandling=NullValueHandling.Ignore,})@CaiusJard当我请求格式为XML时,错误消息来自newtonsoft.json。如果您看到,它告诉您“Newtonsoft.Json.Linq.JToken”上存在递归引用,这就是它无法将其转换为XML的原因。由于我返回要使用的数据的最后一次返回来自Newtonsoft.json,因此您将在详细的错误中看到它。如果需要进一步澄清,请告诉我。错误消息来自newtonsoft.json,但您的投诉是您的xml格式不正确?这对我来说似乎是不匹配的;您使用的是json还是xml?您的查询是否缺少一些可以帮助我们解决问题的细节?您首先从哪里获取Json字符串?@BrianRogers:我从我的模型对象获取Json字符串。使用Newtonsoft的原因是忽略包含null的列。字符串JsonString=JsonConvert.SerializeObject(结果列表,新JsonSerializerSettings{//Formatting=Formatting.Indented,NullValueHandling=NullValueHandling.Ignore,})@CaiusJard当我请求格式为XML时,错误消息来自newtonsoft.json。如果您看到,它告诉您“Newtonsoft.Json.Linq.JToken”上存在递归引用,这就是它无法将其转换为XML的原因。由于我返回要使用的数据的最后一次返回来自Newtonsoft.json,因此您将在详细的错误中看到它。如果需要进一步澄清,请告诉我。看起来像的副本。感谢详细解释。这实际上对我很有用,XMLserliazer也很有效。这就是我要找的。谢谢你