为什么 Blazor 应用程序中的 XML 验证在本地主机上和作为 Azure 静态 Web 应用程序给出不同的消息?

Why is XML validation in a Blazor application giving different messages on localhost and as an Azure Static Web App?

编辑 我在 https://github.com/GilShalit/XMLValidation

做了一个简化的回购

我正在 Blazor WebAssembly (TargetFramework=net5.0) 中构建一个 XML 编辑器。部分功能涉及验证 XML 的完整性并根据具有三个包含的复杂 xsd 架构。

这些是我遵循的步骤:

  1. 构建一个 XmlSchemaSet 并通过为每个 xsd 调用以下方法向其添加 4 个模式:
    private async Task loadSchema(string path, string nameSpace)
    {
        byte[] byteArrayS = await _client.GetByteArrayAsync(path);
        Console.WriteLine($"{path}: {byteArrayS.Length}");
        MemoryStream streamS = new MemoryStream(byteArrayS);
        XmlReader xmlSchemaReader = XmlReader.Create(streamS);
        schemaSet.Add(nameSpace, xmlSchemaReader);
    }
  1. 正在初始化事件处理程序:
ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationEventHandler);
  1. 正在将 XML 加载到 XmlDocument 中:
        byte[] byteArrayX = Encoding.ASCII.GetBytes(await _editorTarget.GetValue());
        MemoryStream streamX = new MemoryStream(byteArrayX);
        XmlReader reader = XmlReader.Create(streamX);
        XmlDocument document = new XmlDocument();
        document.Load(reader);
  1. 正在根据 schemaSet 进行验证:
            document.Schemas = schemaSet;
            document.Validate(eventHandler);

步骤 3 和步骤 4 在 Try...Catch 块中 运行 并且当 XML 格式不正确(例如缺少结束标记)时在本地 运行ning, document.Load(reader); 行产生错误,并显示如下消息:

The 'publicationStmt1' start tag on line 9 position 11 does not match the end tag of 'publicationStmt'. Line 11, position 12.

太棒了。但是验证部署到 Azure 的应用程序中的类似情况会产生以下错误消息:Xml_MessageWithErrorPosition, Xml_TagMismatchEx, 11, 12.

当行 document.Validate(eventHandler); 为 运行 且典型消息为:

时,事件处理程序会捕获架构验证错误
The element 'fileDesc' in namespace 'http://www.tei-c.org/ns/1.0' has invalid child element 'publicationStmt1' in namespace 'http://www.tei-c.org/ns/1.0'. List of possible elements expected: 'editionStmt, extent, publicationStmt' in namespace 'http://www.tei-c.org/ns/1.0'.

但是当 运行 在 Azure 上时,消息是 Sch_InvalidElementContentExpecting

运行本地和 Azure 之间的验证结果差异的原因是什么?

我试图通过添加来禁用链接:

<ItemGroup>
  <BlazorLinkerDescriptor Include="LinkerConfig.xml" />
</ItemGroup>

但这对部署的应用程序没有影响,运行在本地使用 Release 而不是 Debug 也没有改变任何东西。

我还确保在 运行 从 Azure 中加载时确实加载了 4 个 xsd 文件。

Blazor 似乎不包含来自 System.Xml.Res class 的本地化错误消息模板。我的猜测是 Blazor 在通过 CI/CD 管道构建它时将其剥离。您的开发机器和构建代理可能具有不同的语言环境。

我建议使用以下 project properties 尝试强制捆绑所有文化 and/or 加载基于 en_US:

的不变文化
<PropertyGroup>
  <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
<InvariantGlobalization>true</InvariantGlobalization> <!-- If the app doesn't require localization, you may configure the app to support the invariant culture -->
</PropertyGroup>

您还提到了调整 linker,但根据文档,它只在 Release 构建时启动(您似乎还没有尝试部署调试版本)。因此,我建议尝试部署您的应用程序的调试版本,以完全消除 linker。

您还可以强制-link 所有 i18 资源:

<PropertyGroup>
  <BlazorWebAssemblyI18NAssemblies>all</BlazorWebAssemblyI18NAssemblies>
</PropertyGroup>

并将 System.Xml 添加到 LinkerConfig.xml 所以希望它能在没有进一步优化的情况下提供给客户端:

<linker>
  <assembly fullname="System.Xml" />
</linker>

所以这是一个功能而不是错误...

一个issue I opened on Dev community was picked up by the dotnet/runtime team and added to the GitHub issue tracker here.

结果是删除了异常消息以节省大小。

使用 <UseSystemResourceKeys>false</UseSystemResourceKeys> 启用异常消息,我必须说我没有看到大小增加。