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

1

14

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>
Boule answered 19/2, 2019 at 10:40 Comment(3)
My first guess is that it's resolving the wrong relative path - have you tried using an absolute path for xsdPath? e.g. C:\path\to\base.xsd.Hollerman
@CharlesMager: Yes, I come from an XmlReader and I'm now using a full path for xsdPath.Boule
You are comparing .NET Core and Full Framework behaviour, not ASP.NET and desktop. If your ASP.NET Core application targeted the Full Framework you wouldn't see any behaviour. (And yes, ASP.NET Core running on both Core and Full is confusing)Prevailing
H
24

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, as an alternative to the switch you could explicitly set a resolver so that you're not using the default.

Hollerman answered 19/2, 2019 at 10:56 Comment(4)
Jesus I was trying to find out for a day why the same XSD does not validate and XML with the same code running on .NET Core and .NET Framework 4.7.1 Now I know... Thanks.Tatiania
After two days of work trying to figure this out, it works now. Thank you VERY much.Hoxha
Thank God , i found it here .... .NET Core XSD element is not declaredTelpher
Thanks God I found this! And thank you! Cannot believe I wasted a whole day.Calculated

© 2022 - 2024 — McMap. All rights reserved.