ASP.NET Core 1.0 Web API 不返回 XML

Posted

技术标签:

【中文标题】ASP.NET Core 1.0 Web API 不返回 XML【英文标题】:ASP.NET Core 1.0 Web API doesn't return XML 【发布时间】:2015-08-17 14:39:13 【问题描述】:

如何让我的 vnext API 返回 XML 和 JSON?

我认为将 content-type 与 application/xml 一起使用会像以前一样工作。 请注意,我也尝试过 Accept : application/xml。

但似乎没有。

编辑:

这是我的 project.json 文件:


  "webroot": "wwwroot",
  "version": "1.0.0-*",

  "dependencies": 
    "Microsoft.AspNet.Server.IIS": "1.0.0-beta4",
    "Microsoft.AspNet.Server.WebListener": "1.0.0-beta4",
    "Microsoft.AspNet.Mvc": "6.0.0-beta4",
    "Microsoft.AspNet.Mvc.Xml": "6.0.0-beta4"
  ,

  "commands": 
      "web": "Microsoft.AspNet.Hosting --server     Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000"
  ,

  "frameworks": 
    "dnx451":  ,
    "dnxcore50":  
  ,

  "publishExclude": [
    "node_modules",
    "bower_components",
    "**.xproj",
    "**.user",
    "**.vspscc"
  ],
  "exclude": [
    "wwwroot",
    "node_modules",
    "bower_components"
  ]

这是我的 startup.cs:

public class Startup

    // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    
        services.ConfigureMvc(options =>
        
            //options.AddXmlDataContractSerializerFormatter();

            options.InputFormatters.Add(new XmlSerializerInputFormatter());
            options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
        );
        services.AddMvc();
    

    public void Configure(IApplicationBuilder app)
    
        app.UseMvc();
    

【问题讨论】:

【参考方案1】:

.Net Core 1.0.0 发布后更新了详细信息

startup.cs

public void ConfigureServices(IServiceCollection services)

    // Add framework services.
    services.AddMvc(config =>
    
        // Add XML Content Negotiation
        config.RespectBrowserAcceptHeader = true;
        config.InputFormatters.Add(new XmlSerializerInputFormatter());
        config.OutputFormatters.Add(new XmlSerializerOutputFormatter());
    );

项目.json

"dependencies": 
    "Microsoft.AspNetCore.Mvc": "1.0.0",
    "Microsoft.AspNetCore.Mvc.Formatters.Xml": "1.0.0",

如需更多帮助,请参阅 Shawn Wildermuths 关于该主题的博文:Content Negotiation in ASP.NET Core

【讨论】:

不再适用于 MVC 1.0.1!网上好像没有关于这个问题的信息。 我注意到这不起作用。它正在另一个具有完全相同配置和代码的示例项目中工作。我注意到正在运行的项目(即尊重接受标头并按指定返回 json 或 xml)与未运行的项目之间的唯一区别是,在正在运行的项目中,只有 Microsoft.AspNetCore.Mvc.Formatters.Xml(1.0.1) ` 是引用,而在不工作的那个中,Microsoft.AspNetCore.Mvc.Formatters.Json(1.0.1)Microsoft.AspNetCore.Mvc.Formatters.Xml(1.0.1) 按顺序被引用。 是的,none 这里的答案都不再起作用了。这很令人沮丧,因为网上的一切都指向这个问题,现在已经严重过时了。【参考方案2】:

默认情况下,Xml 格式化程序不包含在 Microsoft.AspNet.Mvc 包中。为此,您需要引用另一个名为 Microsoft.AspNet.Mvc.Xml 的包。

如何添加格式化程序的示例:

public IServiceProvider ConfigureServices(IServiceCollection services)

    services.AddMvc();

    services.ConfigureMvc(options =>
    
        // This adds both Input and Output formatters based on DataContractSerializer
        options.AddXmlDataContractSerializerFormatter();

        // To add XmlSerializer based Input and Output formatters.
        options.InputFormatters.Add(new XmlSerializerInputFormatter());
        options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
    );

【讨论】:

谢谢,但现在,我总是得到 xml 我已经用 Accept 进行了测试:application/xml 和 application/json 和 content-type 都...而且我总是得到 XML 你能分享一下你的配置文件是什么样子的吗? 看起来选项的注册方式存在错误。你能重新排序你的电话,以便你先调用AddMvc(),然后再调用ConfigureMvc吗? @Tim: 仅供参考...这个错误现在已经修复,将在下一个版本中提供...即您应该能够在AddMvc 之前或之后调用ConfigureMvc 而无需任何问题。【参考方案3】:

这是 MVC6 rc1 的更新答案

Startup.cs(使用MvcXmlMvcBuilderExtensions)

    public void ConfigureServices(IServiceCollection services)
    
        var mvcBuilder = services.AddMvc();
        mvcBuilder.AddXmlSerializerFormatters();
        // or mvcBuilder.AddXmlDataContractSerializerFormatters()

项目.json

"dependencies": 
    "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
    "Microsoft.AspNet.Mvc.Formatters.Xml": "6.0.0-rc1-final",

不要忘记,因为 ASP.NET 5 已重命名为 ASP.NET Core 1.0,所以 Microsoft.AspNet.Mvc 变成了 Microsoft.AspNetCore.Mvc,即

"dependencies": 
   "Microsoft.AspNetCore.Mvc" : "1.0.2",
   "Microsoft.AspNetCore.Mvc.Formatters.Xml" : "1.0.2",

【讨论】:

【参考方案4】:

面对类似的问题,必须在一个WEB REST API服务中处理,使用ASP .NET MVC Core 1.1.0,两种类型的XML正文请求DataContractSerializerXmlSerializer强>。

因此,在我的情况下,我需要带有 XML 序列化类型参数的 FromXmlBodyXmlResult。 阅读此线程并考虑通过变通方法编写代码,但当我查看 GitHub 时。我发现解决方案已经存在。 我已经检查过了,它看起来像是一个优质的软件工程解决方案。 我想分享链接: 这是 Asp.NET Core 版本的新 XML 扩展。 >=1.1.0 ASP.NET Core MVC 格式化程序的 XmlResult 和 FromXmlBody 扩展,用于使用 DataContractSerializer 和 XmlSerializer 进行 XML 输入和输出。 https://github.com/Wallsmedia/XmlResult 掘金包:https://www.nuget.org/packages/Microsoft.AspNetCore.Mvc.Formatters.Xml.Extensions 它适用于一个服务/控制器/方法中的两种 Xml 序列化类型(DataContractSerializer 和 XmlSerializer)。 这是示例:
 [Route("api/[controller]")]
public class XmlExtController : Controller

    // GET api/[controller]/xml
    [HttpGet("xml")]
    public ActionResult GetXmlObject()
    
        object obj = new PurchaseOrder();
        return new XmlResult(obj);
    

    // GET api/[controller]/dcxml
    [HttpGet("dcxml")]
    public ActionResult GetDcXmlObject()
    
        object obj = new PurchaseOrder();
        return new XmlResult(obj)  XmlSerializerType = XmlSerializerType.DataContractSerializer ;
    

    // POST api/[controller]/xml
    [HttpPost("xml")]
    public void PostXml([FromXmlBody]PurchaseOrder value)
    
        var x = value;
        x.billTo.street += " 123";
    

    // POST api/[controller]/dcxml
    [HttpPost("dcxml")]
    public void PostDcXml([FromXmlBody(XmlSerializerType = XmlSerializerType.DataContractSerializer)]PurchaseOrder value)
    
        var x = value;
        x.billTo.street += "No -10";
    


【讨论】:

【参考方案5】:

ASP.NET Core 1.1 的更新答案:

Startup.cs:

public void ConfigureServices(IServiceCollection services)

    // Add framework services.
    services.AddMvc(config => 
        config.RespectBrowserAcceptHeader = true;
        config.InputFormatters.Add(new XmlSerializerInputFormatter());
        config.OutputFormatters.Add(new XmlSerializerOutputFormatter());
    );            

Csproj:

<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Xml" Version="1.1.3" />

【讨论】:

【参考方案6】:

MVC 6 RespectBrowserAcceptHeader 默认为 false。因此它将绕过内容协商。这就是为什么您可能在启用 XML 格式化程序后总是得到 XML。

您可以通过将以下内容添加到您的启动文件中来将 RespectBrowserAcceptHeader 设置为 true:

services.Configure<MvcOptions>(options =>
        
            options.RespectBrowserAcceptHeader = true;
        );

【讨论】:

【参考方案7】:

您的请求必须发送 AcceptHeader application/xml

Accept:响应可接受的媒体类型,例如 “application/json”、“application/xml”或自定义媒体类型,例如 "应用程序/vnd.example+xml

content-type 定义您发送的内容另请参阅Difference between Accept and ContentType Header

我不确定是否在 asp.net 5 webapi 中默认激活了针对 xml 的内容协商

看过这篇文章:Content Negotiation and Web API for the ASP.NET MVC Developer

【讨论】:

我也试过Accept,我没这么说 那你检查过xml内容协商是否激活了吗?请参阅我帖子中的链接。 这似乎在 ASP.NET 4.X 上,我知道如何使用 web api 2 进行内容协商,但我的问题来自 ASP.NET 5 (vnext)【参考方案8】:

这在 RC2 中被简化为 services.AddMvc().AddXmlDataContractSerializerFormatters();

public void ConfigureServices(IServiceCollection services)
        
            // Add framework services.
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

            services.AddMvc();

            services.AddMvc().AddXmlDataContractSerializerFormatters();

            // Add application services.
            services.AddTransient<IEmailSender, AuthMessageSender>();
            services.AddTransient<ISmsSender, AuthMessageSender>();
        

【讨论】:

以上是关于ASP.NET Core 1.0 Web API 不返回 XML的主要内容,如果未能解决你的问题,请参考以下文章