【问题标题】:Why won't WebAPI return my POCOs as XML?为什么 WebAPI 不会将我的 POCO 作为 XML 返回?
【发布时间】:2013-02-19 19:25:07
【问题描述】:

WebAPI 忽略了传入请求中的 Accept: 标头,并且似乎总是将我的 POCO 对象序列化为 JSON。我正在使用WizTools RestClient 来测试 API 调用,并设置请求 HTTP 标头:

GET /api/people/evh123
Accept: application/xml

如果我修改我的控制器以返回 string[] 或其他一些本机类型,我会得到预期的 XML。我看到有几个人建议将此行添加到我的 Application_Start() 方法中:

GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;

但就我而言,这没有任何区别。

我的 API 控制器:

using System.Web.Http;
using Spyglass.Api.Entities;

namespace Spyglass.Api.Controllers {
    public class PeopleController : ApiController {

        public Person Get(string personId) {
            var member = new Person(personId) { FullName = "Eddie van Halen" };
            return (member);
        }
    }
}

我的路线配置:

using System.Web.Http;

namespace Spyglass.Api {
    public static class WebApiConfig {
        public static void Register(HttpConfiguration config) {
            config.Routes.MapHttpRoute(
                name: "PeopleApi",
                routeTemplate: "api/people/{personId}/{controller}/{id}",
                defaults: new {id = RouteParameter.Optional, controller = "People"}
                );
        }
    }
}

我的 POCO:

namespace Spyglass.Api.Entities {
    public class Person {
        public string PersonId { get; set; }
        public string FullName { get; set; }

        public Person(string personId) {
            this.PersonId = personId;
        }
    }
}

我的 POCO 是否缺少某种自定义序列化配置?没有通常会导致 XML 序列化程序头痛的循环引用或复杂类型......有什么想法吗?

【问题讨论】:

  • 下面的答案可能是正确的(即构造函数);但是,我想指出这个答案,它涵盖了其他潜在问题,并为可能出现的其他问题提出了修复建议stackoverflow.com/questions/11804301/…

标签: serialization asp.net-web-api poco


【解决方案1】:

你需要用 [DataContract] 和 [DataMember] 属性来装饰你的对象

[DataContract]
public class Person
{

    [DataMember]
    public string PersonId { get; set; }

    [DataMember]
    public string FullName { get; set; }

    public Person(string id)
    {
        PersonId = id;
    }
}

或者,确保您的 POCO 具有默认的无参数构造函数。 这是 DataContractSerializer 的限制。您也可以使用不同的序列化程序。

【讨论】:

  • Piotr 是对的,您要么需要添加默认的无参数构造函数,要么添加 DataContract/DataMember 属性以使序列化程序正常工作。
  • 三年后我要加入,但这个问题刚刚发生在我身上。我很好地返回了 JSON,但是当我尝试返回 XML 时,我得到了一个空文档。装饰模型 [DataContract] 和 [DataMember] 解决了它。
【解决方案2】:

您可以尝试从 global.asx.cs 中删除 json 格式化程序;

GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.JsonFormatter);

这将只保留 XML 格式化程序。

【讨论】:

  • 如果我添加该行,我会收到 406 Not Acceptable 响应。
  • 您看到的是 406,因为在内容协商期间询问每个格式化程序是否可以编写特定类型。在这种情况下,XmlMediaTypeFormatter 的 CanWriteType 提到了 false,因此您看到了这个问题。您可以通过执行类似“XmlMediaTypeFormatter frmtr = new XmlMediaTypeFormatter(); bool canWriteType = frmtr.CanWritetype(typeof(Person));”来检查这一点
猜你喜欢
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
  • 1970-01-01
  • 2016-06-18
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多