用于xml架构编译的Full Framework和.NET Core的不同行为

问题描述 投票:0回答:1

这是我的验证码:

string xsdPath = "base.xsd";
XDocument doc = XDocument.Load(xmlPath);
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("http://some.domain.org", xsdPath);
schemas.Compile();
bool isValid = true;
doc.Validate(schemas, (o, e) => {
    res.AddMessage(MessageSeverities.Error, $"{e.Severity}:{e.Message}");
    isValid = false;
});
if ( isValid ) {
    res.AddMessage(
        MessageSeverities.Notice, 
        $"{formFile.FileName} is valid!");
}

在桌面应用程序(.net 4.6)中使用时,此代码运行正常

在.net核心asp 2.1控制器中使用时代码失败,schemas.Compile();引发了以下异常:

XmlSchemaException:未声明类型'http://some.domain.org:tAccountingItemTypes'。

似乎相关的模式文件没有加载到asp核心应用程序中。如何强制加载相关模式?

模式是:

base.xsd

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema 
    targetNamespace="http://some.domain.org" 
    xmlns="http://some.domain.org"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    elementFormDefault="qualified">

    <xs:include id="enums" schemaLocation="enums.xsd"/>

    <xs:complexType name="tAccountingLines">
      <xs:sequence>
        <xs:element name="AccountingLine" type ="tAccountingLine"></xs:element>
      </xs:sequence>
    </xs:complexType>

    <xs:complexType name="tAccountingLine">
      <xs:sequence>
        <xs:element name="AccountingType" type="tAccountingItemTypes"></xs:element>     
        </xs:element>
      </xs:sequence>    
    </xs:complexType>
</xs:schema>

enums.xsd

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema 
  targetNamespace="http://some.domain.org" 
  xmlns="http://some.domain.org"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  elementFormDefault="qualified">

  <xs:simpleType name="tAccountingItemTypes">
    <xs:restriction base="xs:string">
      <xs:enumeration value="V1"/>
      <xs:enumeration value="V2"/>
      <xs:enumeration value="V3"/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>
c# .net xml .net-core xsd-validation
1个回答
7
投票

我刚试过这个,并且它没有加载包含的模式的原因是它用来加载它的解析器是null。这应该解决它:

schemas.XmlResolver = new XmlUrlResolver();

我做了一些挖掘,发现这是一个已知的行为改变Deskop和核心之间的documented here

如果要添加的模式通过外部URI导入另一个模式,则Core在默认情况下不允许解析该URI。要允许Core上的解析,需要在添加模式之前调用以下内容:AppContext.SetSwitch("Switch.System.Xml.AllowDefaultResolver", true);

显然,除了开关之外,您还可以显式设置解析器,这样就不会使用默认值。

© www.soinside.com 2019 - 2024. All rights reserved.