Full Framework和.NET Core用于xml模式编译的不同行为 [英] different behavior for Full Framework and .NET Core for xml schema compilation

查看:126
本文介绍了Full Framework和.NET Core用于xml模式编译的不同行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的验证代码:

  string xsdPath = base.xsd; 
XDocument doc = XDocument.Load(xmlPath);
XmlSchemaSet模式=新的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}有效!);
}

在桌面应用程序(.net 4.6)中使用时,此代码运行良好/ p>

在.net core 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:枚举值= V1 />
< xs:枚举值= V2 />
< xs:枚举值= V3 />
< / xs:restriction>
< / xs:simpleType>
< / xs:schema>


解决方案

我刚刚尝试过它,以及它的原因不会加载包含的架构,因为它用于加载的解析器为 null 。这应该可以解决此问题:

  schemas.XmlResolver = new XmlUrlResolver(); 

我做了一些挖掘,发现这是Deskop& 此处记录的核心


如果要添加的架构通过外部URI导入另一个架构,则Core不允许默认解析该URI,而Desktop则允许。为了允许在Core上进行解析,需要在添加架构之前调用以下内容: AppContext.SetSwitch( Switch.System.Xml.AllowDefaultResolver,true);


很明显,除了此开关之外,您还可以显式设置解析器,以免使用默认设置。


here is my validation code:

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!");
}

this code runs fine when used in a desktop app (.net 4.6)

the code fails when used in a .net core asp 2.1 controller with the following exception raised by schemas.Compile();:

XmlSchemaException: Type 'http://some.domain.org:tAccountingItemTypes' is not declared.

It seems that related schema files are not loaded in the asp core app. How can I force loading of related schemas ?

the schemas are:

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>

解决方案

I've just tried this, and the reason it doesn't load the included schema is that the resolver it uses to load it is null. This should fix it:

schemas.XmlResolver = new XmlUrlResolver();

I've done a bit of digging and found that this is a known behavioural change between Deskop & Core that is documented here:

If the schema being added imports another schema through external URI, Core does not allow resolving that URI by default while Desktop does. To allow the resolution on Core, the following needs to be called before adding the schema: AppContext.SetSwitch("Switch.System.Xml.AllowDefaultResolver", true);

Obviously, in addition to the switch you can explicitly set a resolver so that you're not using the default.

这篇关于Full Framework和.NET Core用于xml模式编译的不同行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆