【问题标题】:net core 3 AddXmlSerializerFormatters() configure optionsnet core 3 AddXmlSerializerFormatters() 配置选项
【发布时间】:2020-02-27 14:14:00
【问题描述】:

应用程序需要能够以正常工作的 Json 和 Xml 格式返回数据。但是,与此 api 接口的应用程序在其结果中不支持命名空间。 <Item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

在此版本之前,我必须编写一个自定义 xml 序列化器来为我执行此操作:

public static string Serialise<T>(T model) where T : class, new()
        {
            // Initalise the Xml writer with required settings.
            XmlWriterSettings settings = new XmlWriterSettings
            {
                OmitXmlDeclaration = true
            };
            // Set the namespaces accordingly.
            XmlSerializerNamespaces xmlNamespaceOverride = new XmlSerializerNamespaces();
            xmlNamespaceOverride.Add("", "");
            string xml = "";
            // Create a new string writer.
            using (StringWriter stringWriter = new StringWriter())
            {
                // And a new Xmlwriter.
                using (XmlWriter writer = XmlWriter.Create(stringWriter, settings))
                {
                    // Serialise the data.
                    new XmlSerializer(typeof(T)).Serialize(writer, model, xmlNamespaceOverride);
                    xml = stringWriter.ToString();
                }
            }
            return xml;
        }

我正在使用 .AddXmlSerializerFormatters();但是在启动时它会产生命名空间。 有没有办法让 net core 3 覆盖 webapi 中的命名空间,而无需我编写自定义序列化程序包装器?

我的测试控制器如下所示:

[Area("Api")]
[Route("test")]
[FormatFilter]
[Produces("application/json", "application/xml")]
public class DeleteMeController : BaseController
{
    public DeleteMeController(SpApiDbContext spApiDbContext) : base(spApiDbContext) { }

    [Route("{format}/{responseType?}")]
    [HttpGet]
    public async Task<ActionResult<List<Item>>> DeleteMe(string format, string responseType = null)
    {
        try
        {
            return responseType switch
            {
                "badrequest" => BadRequest(),
                "error" => throw new Exception(),
                "notfound" => NotFound(),
                "nocontent" => null,
                _ => new List<Item>()
                {
                    Item.Empty(),
                    Item.Empty()
                },
            };
        }
        catch(Exception exception)
        {
            return await ExceptionResponse(exception, "TEST, please ignore.");
        }
    }
}

【问题讨论】:

    标签: xml asp.net-core asp.net-core-webapi asp.net-core-3.0


    【解决方案1】:

    有没有办法让 net core 3 覆盖 webapi 中的命名空间,而无需编写自定义序列化程序包装器?

    默认序列化器中没有这种方式。

    您需要为 xml 创建自定义序列化格式化程序,如下所示:

    public class XmlSerializerOutputFormatterNamespace : XmlSerializerOutputFormatter
    {
        protected override void Serialize(XmlSerializer xmlSerializer, XmlWriter xmlWriter, object value)
        {
            //applying "empty" namespace will produce no namespaces
            var emptyNamespaces = new XmlSerializerNamespaces();
            emptyNamespaces.Add("", "");
            xmlSerializer.Serialize(xmlWriter, value, emptyNamespaces);
        }
    }
    

    Startup.cs:

    services.AddControllers(options =>
    {
         options.OutputFormatters.Add(new XmlSerializerOutputFormatterNamespace());
    }).AddXmlSerializerFormatters();
    

    【讨论】:

    • 这会阻止我的 web api 控制器绑定,我得到一个 404 错误,我错过了什么吗?
    • 对不起@Rena 我编辑了你的答案,但并不打算这样做。我在我的问题中添加了一个示例控制器。
    • 404 表示服务器端没有找到你的请求url。您请求的 url 是什么?另外,您如何在 Startup.cs 中配置您的路由?
    • 例如,url 是 localhost:/test/xml/badrequest。使用默认的 xml 序列化程序时,它的路由很好。添加自定义项时,会抛出 404。
    • 请检查我的回答。仍然需要AddXmlSerializerFormatters();为您服务。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-17
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 2023-02-24
    • 1970-01-01
    • 2023-03-28
    相关资源
    最近更新 更多