5

I upgraded my old application in .Net 4.5. There are some obsolete methods warnings I was getting so thought to resolve them. One of the obsolete methods is XmlValidatingReader. Looked up on the internet and found that XmlReaderSettings is a potential alternate of XmlValidatingReader.

// ==old code==
Hashtable _SchemasCache = new Hashtable();
XmlReader xmlReader = new XmlTextReader(xmlStream);
XmlValidatingReader validatingReader = new XmlValidatingReader(xmlReader);
validatingReader.Schemas.Add(root.Namespace, schemaLocation); // both parametres are string. No error
_SchemasCache.Add(schemaLocation, validatingReader.Schemas);

// ==new code==
var schemaLocation = "res://somepath/Messages.xsd";
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(root.Namespace, schemaLocation); // this line gives error
_SchemasCache.Add(schemaLocation, settings.Schemas);

old code doesn't give any error but the new code gives an error of The URI prefix is not recognized. I couldn't find the reason for this behavior of settings.Schemas.Add(), as it is working fine with XmlValidatingReader. Can anyone help with this?

Edit: Here value of schemaLocation is "res://somepath/Messages.xsd". Because schemaLocation has no Http: or https:// or not a local resource, that is why the error is occurring. How can I add schemas with these values using XmlReaderSettings

Edit 2: as this XSD is an embedded resource, I found some code online for this scenario. I made below code changes.

Assembly asm = Assembly.Load("AssemblyNameWhereXSDis");
Uri uri = new Uri(@"res://p.a.t.h/Autorisatie/Messages.xsd");
string resourceName1 = asm.GetName().Name + uri.AbsolutePath.Replace("/", ".");

using (Stream schemaStream = myAssembly.GetManifestResourceStream(resourceName1))
{
    using (XmlReader schemaReader = XmlReader.Create(schemaStream)) // this line gives error : value(schemaStream) cannot be null
    {
        settings.Schemas.Add(root.Namespace, schemaReader);
    }
}

here, the value of schemaStream is null. And the value of resourceName1 is assemblyname.folder.Message.xsd.

I have made Message.xsd as Embedded Resource from Visual Studio but still not working.

itsho
  • 4,640
  • 3
  • 46
  • 68
Dinav Ahire
  • 581
  • 1
  • 10
  • 30
  • 1
    You need an attribute in the xml defining the namespace like : xmlns:abc="myURL"; – jdweng Nov 27 '19 at 13:57
  • 2
    I suspect that you need to use a schema resolver. Also, this question on the Microsoft forum sounds similar to yours: https://social.msdn.microsoft.com/Forums/en-US/d6fe5a19-6c90-4561-8862-53f6198636e0/quotaccountsxmlquot-gt-quotthe-uri-prefix-is-not-recognizedquot-uhhm-wtf?forum=silverlightnet – kimbert Dec 02 '19 at 16:02

2 Answers2

3

Source of issue

As you figured yourself - URI has to point to a REAL file somewhere - either a URL (HTTP/HTTPS) or a local file ("C:\...").

So, if you prefer using an Embedded Resource instead, you need to use a fully-specified path in the following form: "Namespace.FolderName.Filename.Extension"

Example

using System;
using System.Linq;
using System.Reflection;
using System.Xml;

// ...

// get full resourceName from current assembly using Linq
var messagesResourceFullName = Assembly.GetExecutingAssembly()
                              .GetManifestResourceNames()
                              .Where(n => n.EndsWith("Messages.xsd"));

using (var schemaStream = asm.GetManifestResourceStream(messagesResourceFullName))
{
    if (schemaStream == null) throw new FileNotFoundException();

    using (var schemaReader = XmlReader.Create(schemaStream))
    {
        settings.Schemas.Add(root.Namespace, schemaReader);
    }
}

source

itsho
  • 4,640
  • 3
  • 46
  • 68
  • Hi. Thanks for the answer. 1. How can you use "Where" in this context? it's giving an error that can't user Where for System. Array. 2. GetManifestResourceStream() only takes parameter string or combination of Type and string. – Dinav Ahire Dec 04 '19 at 09:59
  • 1. add `using System.Linq`. 2. there's an overload of a single string, and this is the one I'm using in the example. – itsho Dec 04 '19 at 13:03
0

Add this line in your code : using System.Linq;

xyz
  • 11
  • 3