【问题标题】:.NET core web API, how to change the root name of the XML returned when using IAsyncEnumerable?.NET 核心 Web API,如何更改使用 IAsyncEnumerable 时返回的 XML 的根名称?
【发布时间】:2020-03-26 14:53:14
【问题描述】:

我想在我的 .net core 3.1 web api 中使用新的 IAsyncEnumerable<T>。这没问题,除了我对 XML 根元素的名称不满意。它似乎是 ArrayOfX,我想要像 Xs 这样的东西。我如何做到这一点?

更具体一点。我的控制器:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    [HttpGet]
    public async IAsyncEnumerable<WeatherForecast> Get()
    {
        await Task.Delay(0);
        var rng = new Random();

        for (var index = 1; index < 5; index++)
        {
            yield return new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            };
        }
    }
}

public class WeatherForecast
{
    public DateTime Date { get; set; }
    public int TemperatureC { get; set; }
    public string Summary { get; set; }
}

在 Startup.cs 中:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddMvcCore(options =>
        {
            options.OutputFormatters.Clear(); // Remove json for simplicity
            options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
        });
}

以及 XML 输出:

<ArrayOfWeatherForecast xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><WeatherForecast><Date>2020-03-26T08:39:59.2303161+01:00</Date><TemperatureC>-13</TemperatureC><Summary>Warm</Summary></WeatherForecast><WeatherForecast><Date>2020-03-27T08:39:59.2389359+01:00</Date><TemperatureC>22</TemperatureC><Summary>Sweltering</Summary></WeatherForecast><WeatherForecast><Date>2020-03-28T08:39:59.2389696+01:00</Date><TemperatureC>33</TemperatureC><Summary>Scorching</Summary></WeatherForecast><WeatherForecast><Date>2020-03-29T08:39:59.2389719+02:00</Date><TemperatureC>-2</TemperatureC><Summary>Bracing</Summary></WeatherForecast></ArrayOfWeatherForecast>

如何获取 WeatherForecasts 而不是 ArrayOfWeatherForecast?

【问题讨论】:

  • 看起来问题可能出在 ControllerBase 中。使用 Xml 序列化,您当前有 public WeatherForecast[] WeatherForeCast { get;set;} 要修复,您需要在上一行之前添加 [XmlElement("WeatherVoreCast")]。我相信这是隐藏在 ControllerBase 代码中的。
  • @jdweng 我的演示项目基于 Microsoft 模板进行了一些修改,所有这些都在上面列出。没有 WeatherForecast[] 类型的属性,只有控制器中的 Get() 方法。而 ControllerBase 是标准 mvc(命名空间 Microsoft.AspNetCore.Mvc)的一部分。所以我不确定你的意思。
  • 我就是这么想的。该服务在看到创建两个 xml 标记(ArrayOfWeatherForecast 和 WeatherForecast)的数组时自动进行。该服务使用 Xml 序列化来读取/写入 XML。 XML 不允许将数组作为根元素。如果您只有一个 WeatherForeCast,请从 IAsyncEnumerable 中删除 Enumerable。
  • @jdweng 我想使用 IAsyncEnumerable(有关详细信息,请参阅docs.microsoft.com/en-us/aspnet/core/web-api/…)返回多个项目。不过谢谢你的建议。
  • 你不能吃蛋糕也不能吃馅饼。如果您希望 IAsyncEnumerable 作为 xml 中的根元素,那么您将使用 ArrayOfWeatherForecast。由于您不能在带有序列化的 xml 中将数组作为根。

标签: c# xml asp.net-core asp.net-web-api


【解决方案1】:

您可以编写自己的XmlSerializerOutputFormatter,如下所示:

public class MyCustomXmlSerializerOutputFormatter : XmlSerializerOutputFormatter
{
    protected override void Serialize(XmlSerializer xmlSerializer, XmlWriter xmlWriter, object value)
    {

        xmlSerializer = new XmlSerializer(typeof(List<WeatherForecast>) ,new XmlRootAttribute("WeatherForecasts"));

        xmlSerializer.Serialize(xmlWriter, value);
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddMvcCore(options =>
        {
            options.OutputFormatters.Clear(); // Remove json for simplicity
            options.OutputFormatters.Add(new MyCustomXmlSerializerOutputFormatter());
        });
    }

结果:

【讨论】:

  • 绝对完美。谢谢
猜你喜欢
  • 1970-01-01
  • 2019-10-25
  • 1970-01-01
  • 1970-01-01
  • 2020-05-07
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 1970-01-01
相关资源
最近更新 更多