سؤال

(إذا كان أي شيء هنا يحتاج توضيح/ مزيد من التفاصيل يرجى اسمحوا لي أن أعرف.)

لدي تطبيق (C#, 2.* الإطار) واجهات مع طرف ثالث خدمة ويب باستخدام الصابون.اعتدت thinktecture هو WSCF الإضافية ضد الموردة WSDL لإنشاء العميل التنفيذ.لأسباب خارجة عن إرادتي الصابون تبادل الرسائل يستخدم WSE2.0 الأمنية (thinctecture تنفيذ بد من تعديلها لتشمل WSE2.0 المرجع).بالإضافة إلى "طبيعية" حزمة البيانات أرفق المخزنة X509 cert ثنائي رمز الأمان من السابق الدعوة إلى مختلف خدمات الويب.نحن نستخدم التشفير SSL من نوع ما - أنا لا أعرف التفاصيل.

كل ما يلزم التسلسل/إلغاء التسلسل الوارد في خدمة ويب العميل - يعني عندما يتم إرجاع التحكم إلى لي بعد استدعاء العميل كامل سلسلة XML الموجودة في الصابون الاستجابة ليست متاحة لي - مجرد إلغاء تسلسل المكونات.لا تفهموني خطأ - أعتقد أن هذا أمر جيد لأنه يعني أنني لا أملك أن أفعل ذلك بنفسي.

ومع ذلك ، من أجل أن يكون هناك شيء يستحق تخزين/أرشفة أنا الحاجة إلى إعادة إجراء تسلسل البيانات في العنصر الجذر.هذا يبدو وكأنه مضيعة للموارد منذ النتيجة في الصابون الاستجابة.

الآن سؤالي:كيف يمكنني الحصول على 'مسح' نسخة من الصابون استجابة بحيث لا تضطر إلى إعادة تسلسل كل شيء من أجل تخزين/أرشفة?

تحرير - طلبي هو 'خربة' ويندوز التطبيق تشغيل خدمة شبكة الاتصال - سببها WebsphereMQ العميل الزناد مراقبة.لا أعتقد ASP.صافي الحلول سوف تطبق.

تحرير - منذ توافق في الآراء حتى الآن هو أنه لا يهم ما إذا كان التطبيق الخاص بي هو ASP.NET أو لا ثم سأقدم CodeMelt هو (واستطرادا كريس) حل النار.

هل كانت مفيدة؟

المحلول

يمكنك الاستفادة من SoapExtension من القائمة WSE2.0 الإطار لاعتراض الردود من الخادم.

public class MyClientSOAPExtension : SoapExtension
{

     Stream oldStream;
     Stream newStream;

     // Save the Stream representing the SOAP request or SOAP response into
     // a local memory buffer.
     public override Stream ChainStream( Stream stream )
     {
            oldStream = stream;
            newStream = new MemoryStream();
            return newStream;
     }

    public override void ProcessMessage(SoapMessage message)
    {
       switch (message.Stage)
        {
            case SoapMessageStage.BeforeDeserialize:
                // before the XML deserialized into object.
                break;
            case SoapMessageStage.AfterDeserialize:
                break;        
            case SoapMessageStage.BeforeSerialize:
                break;
            case SoapMessageStage.AfterSerialize:
                break;            
            default:
                throw new Exception("Invalid stage...");
        }       
    }
}

في مرحلة SoapMessageStage.BeforeDeserialize, يمكنك قراءة البيانات المتوقعة تريد من oldstream (مثلا ، استخدام XmlReader).ثم تخزين البيانات المتوقعة في مكان ما على نفسك استخدام أيضا تحتاج إلى الأمام القديمة دفق البيانات إلى newstream خدمة الويب لاحق استخدام هذه البيانات ، على سبيل المثالإلغاء تسلسل XML في الكائنات.

عينة من تسجيل كل حركة المرور على شبكة الإنترنت خدمة من MSDN

نصائح أخرى

هنا هو مثال يمكنك الإعداد باستخدام Visual studio مرجع ويب إلى http://footballpool.dataaccess.eu/data/info.wso?WSDL

في الأساس يجب أن تدرج في خدمة ويب استدعاء سلسلة XmlReader spyer التي من شأنها إعادة بناء الخام XML.

أعتقد أن هذه الطريقة بطريقة ما أبسط أن استخدام SoapExtensions.

الحل كان الحل مستوحاة من http://orbinary.com/blog/2010/01/getting-the-raw-soap-xml-sent-via-soaphttpclientprotocol/

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Reflection;
using System.Xml;


namespace ConsoleApplication1 {

    public class XmlReaderSpy : XmlReader {
        XmlReader _me;
        public XmlReaderSpy(XmlReader parent) {
            _me = parent;
        }

        /// <summary>
        /// Extracted XML.
        /// </summary>
        public string Xml;

        #region Abstract method that must be implemented
        public override XmlNodeType NodeType {
            get {

                return _me.NodeType;
            }
        }

        public override string LocalName {
            get {
                return _me.LocalName;
            }
        }

        public override string NamespaceURI {
            get {
                return _me.NamespaceURI;
            }
        }

        public override string Prefix {
            get {
                return _me.Prefix;
            }
        }

        public override bool HasValue {
            get { return _me.HasValue; }
        }

        public override string Value {
            get { return _me.Value; }
        }

        public override int Depth {
            get { return _me.Depth; }
        }

        public override string BaseURI {
            get { return _me.BaseURI; }
        }

        public override bool IsEmptyElement {
            get { return _me.IsEmptyElement; }
        }

        public override int AttributeCount {
            get { return _me.AttributeCount; }
        }

        public override string GetAttribute(int i) {
            return _me.GetAttribute(i);
        }

        public override string GetAttribute(string name) {
            return _me.GetAttribute(name);
        }

        public override string GetAttribute(string name, string namespaceURI) {
            return _me.GetAttribute(name, namespaceURI);
        }

        public override void MoveToAttribute(int i) {
            _me.MoveToAttribute(i);
        }

        public override bool MoveToAttribute(string name) {
            return _me.MoveToAttribute(name);
        }

        public override bool MoveToAttribute(string name, string ns) {
            return _me.MoveToAttribute(name, ns);
        }

        public override bool MoveToFirstAttribute() {
            return _me.MoveToFirstAttribute();
        }

        public override bool MoveToNextAttribute() {
            return _me.MoveToNextAttribute();
        }

        public override bool MoveToElement() {
            return _me.MoveToElement();
        }

        public override bool ReadAttributeValue() {
            return _me.ReadAttributeValue();
        }

        public override bool Read() {
            bool res = _me.Read();

            Xml += StringView();


            return res;
        }

        public override bool EOF {
            get { return _me.EOF; }
        }

        public override void Close() {
            _me.Close();
        }

        public override ReadState ReadState {
            get { return _me.ReadState; }
        }

        public override XmlNameTable NameTable {
            get { return _me.NameTable; }
        }

        public override string LookupNamespace(string prefix) {
            return _me.LookupNamespace(prefix);
        }

        public override void ResolveEntity() {
            _me.ResolveEntity();
        }

        #endregion


        protected string StringView() {
            string result = "";

            if (_me.NodeType == XmlNodeType.Element) {
                result = "<" + _me.Name;

                if (_me.HasAttributes) {
                    _me.MoveToFirstAttribute();
                    do {
                        result += " " + _me.Name + "=\"" + _me.Value + "\"";
                    } while (_me.MoveToNextAttribute());

                    //Let's put cursor back to Element to avoid messing up reader state.
                    _me.MoveToElement();
                }

                if (_me.IsEmptyElement) {
                    result += "/";
                }

                result += ">";
            }

            if (_me.NodeType == XmlNodeType.EndElement) {
                result = "</" + _me.Name + ">";
            }

            if (_me.NodeType == XmlNodeType.Text || _me.NodeType == XmlNodeType.Whitespace) {
                result = _me.Value;
            }



            if (_me.NodeType == XmlNodeType.XmlDeclaration) {
                result = "<?"  + _me.Name + " " +   _me.Value + "?>";
            }

            return result;

        }
    }

    public class MyInfo : ConsoleApplication1.eu.dataaccess.footballpool.Info {             

        protected XmlReaderSpy _xmlReaderSpy;

        public string Xml {
            get {
                if (_xmlReaderSpy != null) {
                    return _xmlReaderSpy.Xml;
                }
                else {
                    return "";
                }
            }
        }


        protected override XmlReader GetReaderForMessage(System.Web.Services.Protocols.SoapClientMessage message, int bufferSize) {          
            XmlReader rdr = base.GetReaderForMessage(message, bufferSize);
            _xmlReaderSpy = new XmlReaderSpy((XmlReader)rdr);
            return _xmlReaderSpy;
        }

    }

    class Program {
        static void Main(string[] args) {

            MyInfo info = new MyInfo();
            string[] rest = info.Cities();

            System.Console.WriteLine("RAW Soap XML response :\n"+info.Xml);
            System.Console.ReadLine();
        }
    }
}

مستوحاة من jfburdet, أردت أن أرى إذا كان من الممكن مباشرة اعتراض على تيار/بايت مستوى بدلا من إعادة بناء XML.و هو!انظر التعليمات البرمجية أدناه:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web.Services.Protocols;
using System.Xml;

using Test.MyWebReference;

namespace Test {
    /// <summary>
    /// Adds the ability to retrieve the SOAP request/response.
    /// </summary>
    public class ServiceSpy : OriginalService {
        private StreamSpy writerStreamSpy;
        private XmlTextWriter xmlWriter;

        private StreamSpy readerStreamSpy;
        private XmlTextReader xmlReader;

        public MemoryStream WriterStream {
            get { return writerStreamSpy == null ? null : writerStreamSpy.ClonedStream; }
        }

        public XmlTextWriter XmlWriter {
            get { return xmlWriter; }
        }

        public MemoryStream ReaderStream {
            get { return readerStreamSpy == null ? null : readerStreamSpy.ClonedStream; }
        }

        public XmlTextReader XmlReader {
            get { return xmlReader; }
        }

        protected override void Dispose(bool disposing) {
            base.Dispose(disposing);
            DisposeWriterStreamSpy();
            DisposeReaderStreamSpy();
        }

        protected override XmlWriter GetWriterForMessage(SoapClientMessage message, int bufferSize) {
            // Dispose previous writer stream spy.
            DisposeWriterStreamSpy();

            writerStreamSpy = new StreamSpy(message.Stream);
            // XML should always support UTF8.
            xmlWriter = new XmlTextWriter(writerStreamSpy, Encoding.UTF8);

            return xmlWriter;
        }

        protected override XmlReader GetReaderForMessage(SoapClientMessage message, int bufferSize) {
            // Dispose previous reader stream spy.
            DisposeReaderStreamSpy();

            readerStreamSpy = new StreamSpy(message.Stream);
            xmlReader = new XmlTextReader(readerStreamSpy);

            return xmlReader;
        }

        private void DisposeWriterStreamSpy() {
            if (writerStreamSpy != null) {
                writerStreamSpy.Dispose();
                writerStreamSpy.ClonedStream.Dispose();
                writerStreamSpy = null;
            }
        }

        private void DisposeReaderStreamSpy() {
            if (readerStreamSpy != null) {
                readerStreamSpy.Dispose();
                readerStreamSpy.ClonedStream.Dispose();
                readerStreamSpy = null;
            }
        }

        /// <summary>
        /// Wrapper class to clone read/write bytes.
        /// </summary>
        public class StreamSpy : Stream {
            private Stream wrappedStream;
            private long startPosition;
            private MemoryStream clonedStream = new MemoryStream();

            public StreamSpy(Stream wrappedStream) {
                this.wrappedStream = wrappedStream;
                startPosition = wrappedStream.Position;
            }

            public MemoryStream ClonedStream {
                get { return clonedStream; }
            }

            public override bool CanRead {
                get { return wrappedStream.CanRead; }
            }

            public override bool CanSeek {
                get { return wrappedStream.CanSeek; }
            }

            public override bool CanWrite {
                get { return wrappedStream.CanWrite; }
            }

            public override void Flush() {
                wrappedStream.Flush();
            }

            public override long Length {
                get { return wrappedStream.Length; }
            }

            public override long Position {
                get { return wrappedStream.Position; }
                set { wrappedStream.Position = value; }
            }

            public override int Read(byte[] buffer, int offset, int count) {
                long relativeOffset = wrappedStream.Position - startPosition;
                int result = wrappedStream.Read(buffer, offset, count);
                if (clonedStream.Position != relativeOffset) {
                    clonedStream.Position = relativeOffset;
                }
                clonedStream.Write(buffer, offset, result);
                return result;
            }

            public override long Seek(long offset, SeekOrigin origin) {
                return wrappedStream.Seek(offset, origin);
            }

            public override void SetLength(long value) {
                wrappedStream.SetLength(value);
            }

            public override void Write(byte[] buffer, int offset, int count) {
                long relativeOffset = wrappedStream.Position - startPosition;
                wrappedStream.Write(buffer, offset, count);
                if (clonedStream.Position != relativeOffset) {
                    clonedStream.Position = relativeOffset;
                }
                clonedStream.Write(buffer, offset, count);
            }

            public override void Close() {
                wrappedStream.Close();
                base.Close();
            }

            protected override void Dispose(bool disposing) {
                if (wrappedStream != null) {
                    wrappedStream.Dispose();
                    wrappedStream = null;
                }
                base.Dispose(disposing);
            }
        }
    }
}

على مكتبة MSDN يتضمن المثال التعليمات البرمجية للحصول على XML من كل من الطلب والاستجابة التي يمكنك استخدامها للأرشيف.من الواضح أنك سوف تضطر إلى إجراء بعض التغييرات منذ سبيل المثال بتخزين البيانات في ملف نصي ، ولكنها ليست معقدة جدا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top