示例#1
0
        /// <summary>
        /// Send an Http request containing an mtom message to an endpoint and waits for a response.
        /// </summary>
        /// <param name="bodyParts">A reference to the WsMtomBodyParts collection used to generate a mime multipart message.</param>
        /// <param name="endpointAddress">A string containing the endpoint address of a service that will receive
        /// <param name="isOneway">True = don't wait for response, false means wait for a response.</param>
        /// <param name="isChuncked">If true true the message will be chunk encoded.</param>
        /// <returns>
        /// A DpwSoapResponse object containing a WsWsaHeader and an XmlReader or null if no response is received
        /// or parsing fails.
        /// </returns>
        public DpwsSoapResponse SendRequest(ref WsMtomBodyParts bodyParts, string endpointAddress, bool isOneWay, bool isChuncked)
        {
            WsMtomParams mtomParams = new WsMtomParams();
            if (bodyParts.Boundary == null)
                bodyParts.Boundary = Guid.NewGuid().ToString() + '-' + Guid.NewGuid().ToString().Substring(0, 33);
            mtomParams.start = bodyParts.Start;
            mtomParams.boundary = bodyParts.Boundary;
            WsMtom mtom = new WsMtom();
            byte[] message = mtom.CreateMessage(bodyParts);
            WsMessage response = SendRequest(message, endpointAddress, isOneWay, isChuncked, mtomParams);
            if (isOneWay)
                return null;

            XmlReader reader;
            WsWsaHeader header;
            try
            {
                reader = WsSoapMessageParser.ParseSoapMessage(response.Message, out header);
                bodyParts = response.BodyParts;
            }
            catch
            {
                System.Ext.Console.Write("ParseSoapMessage failed.");
                return null;
            }

            return new DpwsSoapResponse(header, reader);
        }
示例#2
0
        /// <summary>
        /// Creates an instance of a WsRequestMessage class, parses the message into mtom body parts and assigns
        /// the start body part to the SoapMessage property.
        /// </summary>
        /// <param name="message">A byte array containing the message received by a transport.</param>
        /// <param name="boundary">A string containing a boundary element if the transport received an mtom message.</param>
        /// <param name="start">
        /// A string containing the ID of the mtom body part that contains the soap envelope
        /// of the mtom attachment.
        /// </param>
        /// <remarks>
        /// Because Mtom message are identified via transport header fields (yuck).
        /// The transport services create this object and pass it to a message processor. If this is a normal soap request, no
        /// additional processing is required and the SoapMessage property is set to the request message. If this is an
        /// Mtom message, the transport header contains an mtom boundary element and start content id needed to parse
        /// the mtom message. The boundary element is used to identify the start and end of mtom body parts sections.
        /// The start content id is used to identify the specific mtom body part that contains a soap envelope that
        /// references the additional body part elements. If an mtom message is created the constructor parses the
        /// mtom message and creates an mtom body parts object. For mtom the constructor also sets the SoapMessage
        /// property to the body part identified by the startContentID parmeter.
        /// </remarks>
        /// <exception cref="ArgumentNullException">If the message parameter is null.</exception>
        public WsMessage(byte[] message, string boundary, string start)
        {
            Debug.Assert(message != null && boundary != null && start != null);

            // Create an mtom object and parse the transport request message.
            WsMtom mtom = new WsMtom(message);

            this.Message = mtom.ParseMessage(boundary);
            this.MessageType = WsMessageType.Mtom;
            this.BodyParts = mtom.BodyParts;

            System.Ext.Console.Write("Mtom message received. " + this.BodyParts.Count + " body parts found.");
            System.Ext.Console.Write("Soap Message:");
            System.Ext.Console.Write(new String(System.Text.Encoding.UTF8.GetChars(this.BodyParts[0].Content.ToArray())));
        }
        /// <summary>
        /// Processes a message
        /// </summary>
        /// <param name="stream">The message being processed.</param>
        /// <param name="ctx">The context associated with the message.</param>
        /// <returns>The handling status for this operation.</returns>
        protected override ChainResult OnProcessInputMessage(ref WsMessage msg, BindingContext ctx)
        {
            if(msg == null) return ChainResult.Abort;
            
            ArrayList props = ctx.BindingProperties;
            if (props != null)
            {
                int len = props.Count;

                for (int j = 0; j < len; j++)
                {
                    BindingProperty prop = (BindingProperty)props[j];

                    if (prop.Name == HttpKnownHeaderNames.ContentType)
                    {
                        string strContentType = ((string)prop.Value).ToLower();

                        if (strContentType.IndexOf("multipart/related;") == 0)
                        {
                            // Create the mtom header class
                            msg.MtomPropeties = new WsMtomParams();

                            // Parse Mtom Content-Type parameters
                            string[] fields = strContentType.Substring(18).Split(';');
                            int fieldsLen = fields.Length;
                            for (int i = 0; i < fieldsLen; ++i)
                            {
                                string type = fields[i];
                                int idx = type.IndexOf('=');

                                if(idx != -1)
                                {
                                    string param = type.Substring(0, idx).Trim();
                                    string value = type.Substring(idx + 1).Trim('\"');
                                    switch (param.ToUpper())
                                    {
                                        case "BOUNDARY":
                                            if (param.Length > 72)
                                                throw new ArgumentException("Mime boundary element length exceeded.", "boundary");
                                            msg.MtomPropeties.boundary = value;
                                            break;
                                        case "TYPE":
                                            msg.MtomPropeties.type = value;
                                            break;
                                        case "START":
                                            msg.MtomPropeties.start = value;
                                            break;
                                        case "START-INFO":
                                            msg.MtomPropeties.startInfo = value;
                                            break;
                                        default:
                                            break;
                                    }
                                }
                            }

                            // Check required Mtom fields
                            if (msg.MtomPropeties.boundary == null || msg.MtomPropeties.type == null || msg.MtomPropeties.start == null)
                            {
                                throw new WsFaultException(msg.Header, WsFaultType.WseInvalidMessage);
                            }

                            WsMtom mtom = new WsMtom((byte[])msg.Body);

                            msg.Body = mtom.ParseMessage(msg.MtomPropeties.boundary);
                            msg.BodyParts = mtom.BodyParts;
                        }
                        else if (strContentType.IndexOf("application/soap+xml") != 0)
                        {
                            throw new WsFaultException(msg.Header, WsFaultType.WseInvalidMessage);
                        }
                    }
                }
            }

            if (msg.Body == null) return ChainResult.Continue;

            MemoryStream requestStream = new MemoryStream((byte[])msg.Body);

            XmlReader reader = XmlReader.Create(requestStream);
            WsWsaHeader hdr = new WsWsaHeader();

            reader.ReadStartElement("Envelope", WsWellKnownUri.SoapNamespaceUri);

            if(ctx.Version.IncludeSoapHeaders)
            {
                hdr.ParseHeader(reader, ctx.Version);
            }
            
            msg.Header = hdr;

            reader.ReadStartElement("Body", WsWellKnownUri.SoapNamespaceUri);


            if(msg.Deserializer != null)
            {
                msg.Body = ((DataContractSerializer)msg.Deserializer).ReadObject(reader);
                reader.Dispose();
            }
            else
            {
                msg.Reader = reader;
            }

            return ChainResult.Continue;
        }
        /// <summary>
        /// Processes a message 
        /// </summary>
        /// <param name="msg">The message being processed.</param>
        /// <param name="ctx">The context associated with the message.</param>
        /// <returns>The handling status for this operation.</returns>
        protected override ChainResult OnProcessOutputMessage( ref WsMessage msg, BindingContext ctx )
        {
            byte[] data = null;

            // if the body is a byte[] then it is already serialized (UDP stuff)
            if (msg == null || (msg.Body != null && msg.Body is byte[])) return ChainResult.Continue;

            // Build response message
            using (XmlMemoryWriter xmlWriter = XmlMemoryWriter.Create())
            {
                WsSoapMessageWriter smw = new WsSoapMessageWriter(ctx.Version);

                // Write start message up to body element content
                smw.WriteSoapMessageStart(xmlWriter, msg, ctx.Version.IncludeSoapHeaders);

                if (msg.Body != null && msg.Serializer != null)
                {
                    DataContractSerializer ser = (DataContractSerializer)msg.Serializer;
                    // Serialize the body element
                    ser.WriteObject(xmlWriter, msg.Body);

                    if(ser.BodyParts != null && ser.BodyParts.Count > 0)
                    {
                        msg.BodyParts = ser.BodyParts;
                    }
                }

                // Write end message
                smw.WriteSoapMessageEnd(xmlWriter);

                data = xmlWriter.ToArray();
            }

            WsMtomBodyParts bodyParts = msg.BodyParts;

            if (bodyParts != null)
            {
                DataContractSerializer reqDcs = (DataContractSerializer)msg.Serializer;

                bodyParts.Start = "<soap@soap>";
                bodyParts.AddStart(reqDcs.CreateNewBodyPart(data, bodyParts.Start));
                if (reqDcs.BodyParts.Count > 0)
                {
                    bodyParts.Add(reqDcs.BodyParts[0]);
                }

                WsMtomParams mtomParams = new WsMtomParams();
                if (bodyParts.Boundary == null)
                    bodyParts.Boundary = Guid.NewGuid().ToString() + '-' + Guid.NewGuid().ToString().Substring(0, 33);
                mtomParams.start = bodyParts.Start;
                mtomParams.boundary = bodyParts.Boundary;
                msg.MtomPropeties = mtomParams;
                WsMtom mtom = new WsMtom();
                data = mtom.CreateMessage(bodyParts);
            }

            msg.Body = data;

            return ChainResult.Continue;
        }