C# Webapi中应用程序/xml的序列化失败

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发

我已更新了问题,请参见更新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也很有效。这就是我要找的。谢谢你