【问题标题】:ASP.NET Core 3.1 using XmlSerializerFormatters()ASP.NET Core 3.1 使用 XmlSerializerFormatters()
【发布时间】:2021-04-05 19:00:06
【问题描述】:

我目前有一个基于 .Net Core 2.2 的应用程序,它可以工作。我需要将此项目移至 .Net Core 3.1,但我似乎无法在控制器中获取 XML 反序列化。在这两个应用程序中,我成功创建了 WCF 连接服务。 WDSL 现在定义了更多类,但基本相同。我区分了文件和 左边是新生成的填充:

<     [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.2")]
---
>     [System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.1-preview-30310-0943")]

这对 Reference.cs 中的每个类都重复。我的问题是我的邮递员测试在新控制器上失败了。通过使用 Calculatus Eliminatus,我设法找出了差异,旧的解析可以接受:

<?xml version="1.0" encoding="UTF-8"?>
<ConnectedServiceRequestX xmlns="http://somename.com/api/01">
    <Timestamp>2021-04-05T16:35:43</Timestamp>
    <ApiKey>TopSecretKey</ApiKey>
    <CustomerId>ABC</CustomerId>
</ConnectedServiceRequestX>

新的解析器只有在发布的 XML 是这样的情况下才能工作:

<?xml version="1.0" encoding="UTF-8"?>
<ConnectedServiceRequestX>
    <Timestamp xmlns="http://somename.com/api/01">2021-04-05T16:35:43</Timestamp>
    <ApiKey xmlns="http://somename.com/api/01">TopSecretKey</ApiKey>
    <CustomerId xmlns="http://somename.com/api/01">ABC</CustomerId>
</ConnectedServiceRequestX>

将 xmlns="http://somename.com/api/01" 放在类级别的 XML 项时,新的解析器会引发异常。我需要支持较旧的 XML 输入,因为我没有访问我们服务的系统的所有权。在这种情况下,一家大公司决定了他们将用来访问我们的数据的界面,而我们是一家小公司。

我倾向于认为我可以为 .XmlSerializerFormatters() 提供一些选项,这样 xmlns 将默认使用类级别 XML 项上提供的命名空间。任何帮助表示赞赏。

【问题讨论】:

    标签: c# xml asp.net-mvc asp.net-core


    【解决方案1】:

    以下应该有效:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Serialization;
    
    
    namespace ConsoleApplication1
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XmlReader reader = XmlReader.Create(FILENAME);
                XmlSerializer serializer = new XmlSerializer(typeof(ConnectedServiceRequestX));
                ConnectedServiceRequestX request = (ConnectedServiceRequestX)serializer.Deserialize(reader);
            }
        }
        [XmlRoot(Namespace = "http://somename.com/api/01")]
        public class ConnectedServiceRequestX
        {
            public DateTime Timestamp { get; set; }
            public string ApiKey { get; set; }
            public string CustomerId { get; set; }
        }
    }
    

    【讨论】:

    • 谢谢@jdweng。如果您查看我的解决方案,基本上您所建议的只是我使用了 XmlRootAttribute 而不是 XmlRoot。
    • 我也看到了。但是有人给了我负面的分数。
    【解决方案2】:

    在研究了生成的文件(2019 年 4 月和今天)之间的差异之后,我注意到一些类之前有一行差异。从 WDSL 生成的 C# 文件中有 60 多个类(我很抱歉之前没有注意到)。无论如何,该行如下:

     [XmlRootAttribute("ConnectedServiceRequestX", Namespace="http://somename.com/api/01", IsNullable = false)]
    

    这些行是我们在类生成之后但在它们最初进入源代码控制之前添加的。他们需要:

    using System.Xml.Serialization;
    

    也将被添加。这样做是允许将 xmlns 属性放置在外部标记(类项标记)中,而不必复制到内部标记中,如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <ConnectedServiceRequestX xmlns="http://somename.com/api/01">
        <Timestamp>2021-04-05T16:35:43</Timestamp>
        <ApiKey>TopSecretKey</ApiKey>
        <CustomerId>ABC</CustomerId>
    </ConnectedServiceRequestX>
    

    我的 Postman 遗留测试是这样设计的。我在学习 ASP.Net Web 服务时编写(生成)此代码,但我不记得修改生成的文件以使 Connected Service / XML Post 工作。所以简短的回答是,当使用 Visual Studio 生成代码(添加连接服务 - WCF/WDSL)时,Reference.cs 文件可能仍会进行一些修改,从而允许将更友好的 XML 发布到端点。

    我现在使用我的旧测试启动并运行 (ASP.NET Core 3.1),这让我有信心使用更新后的应用程序投入生产。我希望这对其他人有所帮助。

    【讨论】:

      猜你喜欢
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2020-07-22
      • 2020-07-14
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      相关资源
      最近更新 更多