Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

different behavior for Full Framework and .NET Core for xml schema compilation

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>
like image 582
tschmit007 Avatar asked Feb 19 '19 10:02

tschmit007


1 Answers

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 Desktop & 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.

like image 164
Charles Mager Avatar answered Oct 20 '22 00:10

Charles Mager