コード例 #1
0
        /// <summary>
        /// processes the inbound message part
        /// </summary>
        /// <param name="pc"></param>
        /// <param name="inmsg"></param>
        /// <param name="outmsg"></param>
        /// <param name="part"></param>
        private void ProcessPart(IPipelineContext pc, IBaseMessage inmsg, IBaseMessage outmsg, IBaseMessagePart part)
        {
            IDocumentSpec docSpec = null;

            Stream dataStream = part.GetOriginalDataStream();
            MarkableForwardOnlyEventingReadStream eventingDataStream = new MarkableForwardOnlyEventingReadStream(dataStream);

            XmlSchemaCollection schemaCollection = new XmlSchemaCollection(new NameTable());

            schemaCollection.ValidationEventHandler += new ValidationEventHandler(this.ValidationCallBack);

            // retrieve the assigned document schemas to validate against
            SchemaList docSchemas = this.DocumentSchemas;

            // retrieve the namespace this document adheres to
            string contextProperty = (string)outmsg.Context.Read(XmlCompleteValidator._documentSpecNameProperty.Name.Name, XmlCompleteValidator._documentSpecNameProperty.Name.Namespace);

            // if the inbound message has a namespace,
            if (contextProperty != null && contextProperty.Length > 0)
            {
                // clear the original schemas to validate against
                docSchemas.Clear();

                string[] contextSchemas = contextProperty.Split(new char[] { '|' });

                // set it's schemas
                foreach (string schemaName in contextSchemas)
                {
                    docSchemas.Add(new Schema(schemaName));
                }
            }

            #region retrieve validation schemas, shamelessly copied from the original XmlValidator pipeline component
            bool validateSchemas = this.DocumentSchemas != null && this.DocumentSchemas.Count > 0;
            if (validateSchemas && this.DocumentSchemas.Count == 1 && this.DocumentSchemas[0].SchemaName.Length == 0)
            {
                validateSchemas = false;
            }

            if (validateSchemas)
            {
                foreach (Schema s in docSchemas)
                {
                    try
                    {
                        docSpec = pc.GetDocumentSpecByName(s.SchemaName);
                    }
                    catch (COMException e)
                    {
                        throw new XmlCompleteValidatorException(
                                  ExceptionType.CANNOT_GET_DOCSPEC_BY_NAME,
                                  e.ErrorCode.ToString("X") + ": " + e.Message,
                                  new string[] { s.SchemaName });
                    }

                    if (docSpec == null)
                    {
                        throw new XmlCompleteValidatorException(
                                  ExceptionType.CANNOT_GET_DOCSPEC_BY_NAME,
                                  string.Empty,
                                  new string[] { s.SchemaName });
                    }

                    XmlSchemaCollection coll = docSpec.GetSchemaCollection();

                    schemaCollection.Add(coll);
                }
            }
            else
            {
                try
                {
                    docSpec = pc.GetDocumentSpecByType(Utils.GetDocType(eventingDataStream));
                }
                catch (COMException e)
                {
                    throw new XmlCompleteValidatorException(
                              ExceptionType.CANNOT_GET_DOCSPEC_BY_TYPE,
                              e.ErrorCode.ToString("X") + ": " + e.Message,
                              new string[] { Utils.GetDocType(eventingDataStream) });
                }

                if (docSpec == null)
                {
                    throw new XmlCompleteValidatorException(
                              ExceptionType.CANNOT_GET_DOCSPEC_BY_TYPE,
                              string.Empty,
                              new string[] { Utils.GetDocType(eventingDataStream) });
                }

                schemaCollection = docSpec.GetSchemaCollection();
            }
            #endregion

            // the most critical line within this component, assign an
            // XmlEventingValidationStream to ensure the inbound messagestream is validated
            // and events can be assigned which allow us to capture any erros that might occur
            XmlEventingValidationStream validatingStream = new XmlEventingValidationStream(eventingDataStream);

            // add the schemas we'd like to validate the inbound message against
            validatingStream.Schemas.Add(schemaCollection);

            // assign a validation event which will accumulate any errors within the inbound message
            validatingStream.ValidatingReader.ValidationEventHandler += new ValidationEventHandler(XmlMessageValidationCallBack);

            // and assign the AfterLastReadEvent, which fires upon reading the last piece of information
            // from the inbound message stream and pushes all accumulated error information out into
            // the eventviewer and onto the HAT context by throwing an exception which contains the errors
            validatingStream.AfterLastReadEvent += new AfterLastReadEventHandler(validatingStream_AfterLastReadEvent);

            // duplicate the inbound message part by creating a new one and copying it's properties
            IBaseMessageFactory messageFactory = pc.GetMessageFactory();
            IBaseMessagePart    messagePart    = messageFactory.CreateMessagePart();

            // if the inbound message exists and has a body part, copy the part properties
            // into the outbound messagepart
            if (inmsg != null && inmsg.BodyPart != null)
            {
                messagePart.PartProperties = PipelineUtil.CopyPropertyBag(inmsg.BodyPart.PartProperties, messageFactory);
            }

            // set the outbound charset
            messagePart.Charset = "UTF-8";

            // set the outbound content type
            messagePart.ContentType = "text/xml";

            // and assign the outbound datastream
            messagePart.Data = validatingStream;

            // finally, copy existing message parts
            CopyMessageParts(pc, inmsg, outmsg, messagePart, false);
        }