XML Validator – C# code – catching errors problem

Home Page Forums BizTalk 2004 – BizTalk 2010 XML Validator – C# code – catching errors problem

Viewing 1 reply thread
  • Author
    Posts
    • #14132

      Hello, I’m working in a project where one of the requirements is to validate an incoming or outgoing document against the schema, catching the error messages that may appear while failing validation. I looked on the web for answers, and the best I could find is in the following site:

      http://thearchhacker.blogspot.com/2004/09/cool-xsd-validation-function-for.html

      Because I wanted the function to return multiple errors (and not just the first failure) I have modified the code to the following:

      [code:1:42eadef361]
      using System;
      using System.Collections.Generic;
      using System.Text;
      using System.Xml;
      using System.Xml.Schema;
      using System.Reflection;

      namespace BiztalkUtils
      {
      public class Utils
      {
      static int ErrorsCount = 0;
      static string ErrorMessage = \"\";

      public static void ValidateDocument(XmlDocument businessDocument, string schemaStrongName)
      {
      // Constants
      const int PARTS_IN_SCHEMA_STRONG_NAME = 2;
      const int PART_CLASS_NAME = 0;
      const int PART_QUALIFIED_ASSEMBLY_NAME = 1;

      ErrorsCount = 0;
      ErrorMessage = \"\";

      // Parse schema strong name
      string[] assemblyNameParts = schemaStrongName.Split(new char[] { ‘,’ }, PARTS_IN_SCHEMA_STRONG_NAME);
      string className = assemblyNameParts[PART_CLASS_NAME].Trim();
      string fullyQualifiedAssemblyName = assemblyNameParts[PART_QUALIFIED_ASSEMBLY_NAME].Trim();

      // Load assembly
      Assembly schemaAssembly = Assembly.Load(fullyQualifiedAssemblyName);

      // Create instance of the BTS schema in order to get to the actual schemas
      Type schemaType = schemaAssembly.GetType(className);
      Microsoft.XLANGs.BaseTypes.SchemaBase btsSchemaCollection = (Microsoft.XLANGs.BaseTypes.SchemaBase)Activator.CreateInstance(schemaType);

      // Set up XmlVali######Reader and validate document
      XmlParserContext parserContext = new XmlParserContext(null,null, \"\", XmlSpace.None);
      XmlVali######Reader reader = new XmlVali######Reader(businessDocument.OuterXml, XmlNodeType.Document,parserContext);

      reader.ValidationType = ValidationType.Schema;
      reader.Schemas.Add(btsSchemaCollection.SchemaCollection);

      // Set up ValidationEventHandler
      reader.ValidationEventHandler += new ValidationEventHandler(reader_ValidationEventHandler);

      while (reader.Read()) { }

      reader.Close();

      // Throw XmlSchemaException to be caught by BizTalk containing all validation errors
      if (ErrorsCount > 0)
      {
      throw new System.Xml.Schema.XmlSchemaException(ErrorMessage);
      }
      }

      private static void reader_ValidationEventHandler(object sender, ValidationEventArgs e)
      {
      ErrorsCount++;

      //Construct error message
      ErrorMessage = ErrorMessage
      + \"Error #\" + ErrorsCount
      + \" (Line \" + e.Exception.LineNumber
      + \", Pos \" + e.Exception.LinePosition + \"): \"
      + e.Exception.Message
      + System.Environment.NewLine;
      }

      }

      }
      [/code:1:42eadef361]

      Note: Substitute \”######\” in the code with [i:42eadef361]d`a`t`i`n`g[/i:42eadef361] (without the \”‘\”) as the spam blocker would not let me attach the code otherwise.

      This works perfectly when I test my orchestration and validate 1 or a few xml files at a time. However, when I try to validate 100 files at once (50 valid and 50 invalid), I get unpredictable behaviors (the number of files that pass validation is not always 50, and the error messages sometimes get \”mixed up\” between the different messages).

      I am not an expert in C#, but I think there may be something wrong with the class I’m using.

      I also tried putting the call to the validation function inside an Atomic Scope, disabling batching and playing with the other settings, but the different instances that are being run by BizTalk still seem to interfere with each other. As I said, if I validate just one file at a time, everything works perfectly.

      I would REALLY appreciate any comments and help on why this behavior may be occuring. Thanks

      • #14133

        [… continued from previous… ]

        This works perfectly when I test my orchestration and validate 1 or a few xml files at a time. However, when I try to validate 100 files at once (50 valid and 50 invalid), I get unpredictable behaviors (the number of files that pass validation is not always 50, and the error messages sometimes get \”mixed up\” between the different messages).

        I am not an expert in C#, but I think there may be something wrong with the class I’m using.

        I also tried putting the call to the validation function inside an Atomic Scope, disabling batching and playing with the other settings, but the different instances that are being run by BizTalk still seem to interfere with each other. As I said, if I validate just one file at a time, everything works perfectly.

        I would REALLY appreciate any comments on why this behavior may be occuring. Thanks

        • #14134

          [quote:8cc6858bba=\”Stephen W. Thomas\”]
          If not, you might want to try [ThreadStatic] as this will create a new object per thread (I think – never actually tried it).
          [/quote:8cc6858bba]

          I tried the [ThreadStatic] approach and now it seems to be working fine! I will test this a little more to be sure, but thanks for the response!

          • #14135

            I still need a little help here… I started using the same validation class in a BizTalk 2006 solution. It is still working perfectly, but because the XmlVali######Reader is obsolete in .Net 2.0, I’m getting warnings. I tried modifying the class to use the following code instead of the XmlVali######Reader approach:

            [code:1:144a86be14]
            // Set up XmlVali######Reader and validate document – OBSOLETE!
            //Using XmlReaderSettings instead

            XmlReaderSettings settings = new XmlReaderSettings();

            settings.ValidationType = ValidationType.Schema;

            XmlReader reader = XmlReader.Create(new System.IO.StringReader(businessDocument.OuterXml), settings);
            foreach (XmlSchema xschema in btsSchemaCollection.SchemaCollection)
            {
            settings.Schemas.Add(xschema);
            }

            settings.ValidationEventHandler += new ValidationEventHandler(reader_ValidationEventHandler);

            while (reader.Read()) { }

            reader.Close();[/code:1:144a86be14]

            However this is not getting my document validated at all (it always validates fine even when it shouldn’t). Any idea on what could I be missing? Thanks again for the help

            • #21786

              nothing man.

            • #22354

               

               

               

               

               

              Just need to add some of theese validation flags.

              settings.ValidationType =

               

              ValidationType

              .Schema;

              settings.ValidationFlags |=

               

              XmlSchemaValidationFlags

              .ProcessInlineSchema;

               

               

              //settings.ValidationFlags |= XmlSchemaValidationFlags.AllowXmlAttributes;

              settings.ValidationFlags |=

               

              XmlSchemaValidationFlags

              .ProcessSchemaLocation;

              settings.ValidationFlags |=

               

              XmlSchemaValidationFlags

              .ProcessIdentityConstraints;

              settings.ValidationFlags |=

               

              XmlSchemaValidationFlags

              .ReportValidationWarnings;

              • #23258

                Rather than calling xmlReader.Close, wrap use of the xmlReader in a using statement:

                            using(XmlReader reader = XmlReader.Create(xpathNavigator.ReadSubtree(), settings))
                            {

                                while (reader.Read()) {}
                            }

      • #23768

        Hello

         

        I have a problem to catch the System.Xml.Schema.XmlSchemaException in the orchestration.

        Exception Object Type = System.Xml.Schema.XmlSchemaException

        it works only with the Exception Object Type = System.Exception

         

         

         

        • #25665

          all exception handling can be done in the scope!! even schema exception handling also!!

    • #14131

      I think the problem is that the method is Static. I have had problems with that in the past.

      I’m guessing it’s static since it is working with Xml items that are not serilizable even if you marked the class that way.

      First off, I’d make the class an instance class and mark it serilizable to see if that works.

      If not, you might want to try [ThreadStatic] as this will create a new object per thread (I think – never actually tried it).

      If neither of those works, you’ll have to make it non serilizable and an instance object thus calling it inside an Atomic Scope shape.

      Let me know how it goes.

Viewing 1 reply thread
  • The forum ‘BizTalk 2004 – BizTalk 2010’ is closed to new topics and replies.