【问题标题】:Xml Requests do not workXml 请求不起作用
【发布时间】:2023-03-25 04:38:01
【问题描述】:

我无法让一个简单的 Asp.Net Core Web Api 项目使用 Xml 而不是 Json 工作。请帮忙!

我创建了一个新项目,对默认配置的唯一调整是添加 Xml 格式化程序...

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddApplicationInsightsTelemetry(Configuration);

    services.AddMvc(config =>
    {
        config.InputFormatters.Add(new XmlSerializerInputFormatter());
        config.OutputFormatters.Add(new XmlSerializerOutputFormatter());
    });
}

我的控制器还包含简单的 Get 和 Post 方法:

[Route("api")]
public class MessageController : Controller
{
    [HttpPost]
    public void Post([FromBody] Message message)
    {

    }

    [HttpGet]
    public IActionResult Get()
    {
        return Ok(new Message
        {
            TestProperty = "Test value"
        });
    }
}

当我尝试使用 Content-Type: application/xml 调用 POST 方法时,API 返回 415 Unsupported Media Type。我已经尝试将Consumes("application/xml") 属性添加到控制器,但它仍然不起作用。

GET 工作并返回 JSON。但是,如果我将 Produces("application/xml") 属性添加到控制器,即使我提供了 Accepts: application/xml 标头,GET 也会返回 406 Not Acceptable。

由于某种原因,API 完全拒绝与 xml 相关的任何内容,即使添加了输入和输出格式化程序,正如我在我能找到的极少数示例中看到的那样。

我错过了什么?

【问题讨论】:

  • 这不应该默认使用 XML 而无需添加任何东西吗?
  • 否,默认情况下 Asp.Net 核心仅包含 Json 格式化程序。需要显式添加 Xml 格式化程序。除了它们显然不起作用......
  • @frangelico87 您是否尝试设置config.RespectBrowserAcceptHeader = true;。根据这篇文章(wildermuth.com/2016/03/16/Content_Negotiation_in_ASP_NET_Core) 是需要的。
  • 是的。据我了解,这只需要指定响应格式。无论哪种方式,是的,我已经尝试过了,但它也不起作用。
  • @frangelico87 对于输入格式化程序官方文档说使用 services.AddMvc() .AddXmlSerializerFormatters(); 。见docs.asp.net/en/latest/mvc/models/…

标签: c# asp.net-core asp.net-core-webapi


【解决方案1】:

对于 ASP.NET Core 2.2,使用 nuget 包 Microsoft.AspNetCore.Mvc.Formatters.XmlMicrosoft.AspNetCore.App 并将其添加到 Startup.cs

      services.AddMvc()
       .AddXmlSerializerFormatters()
       .AddXmlDataContractSerializerFormatters();

不要忘记使用标头 Accept application/xml 以获取 xml 格式的响应,并使用 Content-Type application/xml 获取带有 xml 正文的请求。

在此处查看示例http://www.devcode4.com/article/asp-net-core-xml-request-response

【讨论】:

    【解决方案2】:

    在 ASP.Net Core 2.0 中,您几乎可以立即接受 XML 和 Json 请求。

    在 ConfigureServices 方法的 Startup 类中,您应该有:

    services
        .AddMvc()
        .AddXmlSerializerFormatters();
    

    接受复杂对象的控制器如下所示:

    [Route("api/Documents")]
    public class DocumentsController : Controller
    {
        [Route("SendDocument")]
        [HttpPost]
        public ActionResult SendDocument([FromBody]DocumentDto document)
        {
            return Ok();
        }
    }
    

    这是要发送的 XML:

    <document>
        <id>123456</id>
    <content>This is document that I posted...</content>
    <author>Michał Białecki</author>
    <links>
        <link>2345</link>
        <link>5678</link>
    </links>
    

    {
        id: "1234",
        content: "This is document that I posted...",
        author: "Michał Białecki",
        links: {
            link: ["1234", "5678"]
        }
    }
    

    就是这样!它只是工作。

    使用 XML 或 Json 格式向 api/documents/SendDocument 端点发送相同文档的请求由一种方法处理。只记住请求中正确的 Content-Type 标头。

    您可以在我的博客上阅读整篇文章:http://www.michalbialecki.com/2018/04/25/accept-xml-request-in-asp-net-mvc-controller/

    【讨论】:

      【解决方案3】:

      我的 startup.cs 中有以下内容,它适用于 XML 和 JSON。 这里我只坚持使用 XML。 注意:(我已经考虑过我自己的类作为示例)

      1. Startup.cs

        public void ConfigureServices(IServiceCollection services)
            { 
                services.AddMvcCore()
                        .AddJsonFormatters().AddXmlSerializerFormatters();
            }
        
      2. 我的 HttpClient 代码(您可能错过了我在 StringCotent 中所做的 Content Type 设置)

        • 两个标题很重要:Accept 和 Content-Type。接受内容协商的帮助,Content-Type 是客户端告诉服务器客户端发布的内容类型的一种方式。

           HttpClient client = new HttpClient();
           client.BaseAddress = new Uri( @"http://localhost:5000");
           client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml"));
          
          
           HttpContent content = new StringContent(@"<Product>
          <Id>122</Id>
          <Name>Computer112</Name></Product>",System.Text.Encoding.UTF8 , "application/xml");  // This is important.
          
          var result = client.PostAsync("/api/Products", content).Result;
          

      【讨论】:

      • +1 很好的答案,但我认为只有Content-Type: application/xml 对POST 很重要,因为返回值voidAccept: application/xml 对于 GET 可能很重要。此外,可以考虑使用AddXmlDataContractSerializerFormatters 而不是AddXmlSerializerFormatters,因为它支持更多的数据类型(如Dictionary)。
      猜你喜欢
      • 1970-01-01
      • 2011-04-26
      • 2012-09-10
      • 2013-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多