Comment puis-je obtenir la requête SOAP XML d'une demande de service Web de la FMC?

j'appelle ce service web dans le code et je voudrais voir le XML, mais je ne peux pas trouver une propriété qui l'expose.

60
demandé sur informatik01 2011-03-31 03:20:42

7 réponses

je pense que vous vouliez dire que vous voulez voir le XML sur le client, pas le tracer sur le serveur. Dans ce cas, votre réponse se trouve dans la question I liée ci-dessus, et aussi à Comment inspecter ou modifier les Messages sur le Client . Mais, puisque la version .NET 4 de cet article manque son numéro C, et que L'exemple .NET 3.5 contient une certaine confusion (si ce n'est un bug), il est ici développé pour votre usage.

, Vous pouvez intercepter le message avant qu'il ne passe en utilisant un IClientMessageInspector :

using System.ServiceModel.Dispatcher;
public class MyMessageInspector : IClientMessageInspector
{ }

les méthodes de cette interface, BeforeSendRequest et AfterReceiveReply , vous donnent accès à la requête et à la réponse. Pour utiliser l'inspecteur, vous devez l'ajouter à un IEndpointBehavior :

using System.ServiceModel.Description;
public class InspectorBehavior : IEndpointBehavior
{
    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(new MyMessageInspector());
    }
}

Vous pouvez laisser les autres méthodes de cette interface implémentations vides, sauf si vous souhaitez utiliser cette fonctionnalité, trop. Lire le how-to pour plus de détails.

après avoir instancié le client, ajoutez le comportement au paramètre. À l'aide de noms par défaut à partir de l'exemple de la WCF projet:

ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
client.Endpoint.Behaviors.Add(new InspectorBehavior());
client.GetData(123);

définit un point de rupture dans MyMessageInspector.BeforeSendRequest() ; request.ToString() est surchargé pour afficher le XML.

si vous voulez manipuler les messages, vous devez travailler sur une copie du message. Voir en utilisant la classe de Message pour plus de détails.

merci à la réponse de Zach Bonham à une autre question pour trouver ces liens.

118
répondu Kimberly 2017-05-23 11:33:26

Option 1

Use message tracking/logging .

Ont un look ici et ici .


Option 2

vous pouvez toujours utiliser Fiddler pour voir les requêtes HTTP et la réponse.


Option 3

Use System.Net traçage .

27
répondu Aliostad 2011-03-30 23:27:36
OperationContext.Current.RequestContext.RequestMessage 

ce contexte est accessible côté serveur pendant le traitement de la requête. Cela ne fonctionne pas pour les opérations

6
répondu Alexus1024 2014-02-27 07:23:54

simplement nous pouvons tracer le message de demande sous.

OperationContext context = OperationContext.Current;

if (context != null && context.RequestContext != null)

{

Message msg = context.RequestContext.RequestMessage;

string reqXML = msg.ToString();

}
6
répondu Shebin 2015-02-18 07:26:36

je voulais juste ajouter à la réponse de Kimberly. Peut-être qu'il peut gagner du temps et éviter les erreurs de compilation pour ne pas mettre en œuvre toutes les méthodes que l'interface IEndpointBehaviour nécessite.

meilleures salutations

Nicki

    /*
        // This is just to illustrate how it can be implemented on an imperative declarared binding, channel and client.

        string url = "SOME WCF URL";
        BasicHttpBinding wsBinding = new BasicHttpBinding();                
        EndpointAddress endpointAddress = new EndpointAddress(url);

        ChannelFactory<ISomeService> channelFactory = new ChannelFactory<ISomeService>(wsBinding, endpointAddress);
        channelFactory.Endpoint.Behaviors.Add(new InspectorBehavior());
        ISomeService client = channelFactory.CreateChannel();
    */    
        public class InspectorBehavior : IEndpointBehavior
        {
            public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
            {
                // No implementation necessary  
            }

            public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
            {
                clientRuntime.MessageInspectors.Add(new MyMessageInspector());
            }

            public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
            {
                // No implementation necessary  
            }

            public void Validate(ServiceEndpoint endpoint)
            {
                // No implementation necessary  
            }  

        }

        public class MyMessageInspector : IClientMessageInspector
        {
            public object BeforeSendRequest(ref Message request, IClientChannel channel)
            {
                // Do something with the SOAP request
                string request = request.ToString();
                return null;
            }

            public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
            {
                // Do something with the SOAP reply
                string replySoap = reply.ToString();
            }
        }
1
répondu Nicki 2018-03-23 09:45:00

j'utilise la solution ci-dessous pour IIS hébergement en ASP.NET mode de compatibilité. Les crédits à Rodney de Viana MSDN blog .

ajouter ce qui suit à votre site web.la config dans appSettings:

<add key="LogPath" value="C:\logpath" />
<add key="LogRequestResponse" value="true" />

remplacez votre global.asax.cs avec ci-dessous (aussi fixer le nom de l'espace de noms):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;

using System.Text;
using System.IO;
using System.Configuration;

namespace Yournamespace
{
    public class Global : System.Web.HttpApplication
    {
        protected static bool LogFlag;
        protected static string fileNameBase;
        protected static string ext = "log";

        // One file name per day
        protected string FileName
        {
            get
            {
                return String.Format("{0}{1}.{2}", fileNameBase, DateTime.Now.ToString("yyyy-MM-dd"), ext);
            }
        }

        protected void Application_Start(object sender, EventArgs e)
        {
            LogFlag = bool.Parse(ConfigurationManager.AppSettings["LogRequestResponse"].ToString());
            fileNameBase = ConfigurationManager.AppSettings["LogPath"].ToString() + @"\C5API-";   
        }

        protected void Session_Start(object sender, EventArgs e)
        {

        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {
            if (LogFlag) 
            {                
                // Creates a unique id to match Rquests with Responses
                string id = String.Format("Id: {0} Uri: {1}", Guid.NewGuid(), Request.Url);
                FilterSaveLog input = new FilterSaveLog(HttpContext.Current, Request.Filter, FileName, id);
                Request.Filter = input;
                input.SetFilter(false);
                FilterSaveLog output = new FilterSaveLog(HttpContext.Current, Response.Filter, FileName, id);
                output.SetFilter(true);
                Response.Filter = output;
            }
        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {

        }

        protected void Application_Error(object sender, EventArgs e)
        {

        }

        protected void Session_End(object sender, EventArgs e)
        {

        }

        protected void Application_End(object sender, EventArgs e)
        {

        }
    }

    class FilterSaveLog : Stream
    {

        protected static string fileNameGlobal = null;
        protected string fileName = null;

        protected static object writeLock = null;
        protected Stream sinkStream;
        protected bool inDisk;
        protected bool isClosed;
        protected string id;
        protected bool isResponse;
        protected HttpContext context;

        public FilterSaveLog(HttpContext Context, Stream Sink, string FileName, string Id)
        {
            // One lock per file name
            if (String.IsNullOrWhiteSpace(fileNameGlobal) || fileNameGlobal.ToUpper() != fileNameGlobal.ToUpper())
            {
                fileNameGlobal = FileName;
                writeLock = new object();
            }
            context = Context;
            fileName = FileName;
            id = Id;
            sinkStream = Sink;
            inDisk = false;
            isClosed = false;
        }

        public void SetFilter(bool IsResponse)
        {


            isResponse = IsResponse;
            id = (isResponse ? "Reponse " : "Request ") + id;

            //
            // For Request only read the incoming stream and log it as it will not be "filtered" for a WCF request
            //
            if (!IsResponse)
            {
                AppendToFile(String.Format("at {0} --------------------------------------------", DateTime.Now));
                AppendToFile(id);

                if (context.Request.InputStream.Length > 0)
                {
                    context.Request.InputStream.Position = 0;
                    byte[] rawBytes = new byte[context.Request.InputStream.Length];
                    context.Request.InputStream.Read(rawBytes, 0, rawBytes.Length);
                    context.Request.InputStream.Position = 0;

                    AppendToFile(rawBytes);
                }
                else
                {
                    AppendToFile("(no body)");
                }
            }

        }

        public void AppendToFile(string Text)
        {
            byte[] strArray = Encoding.UTF8.GetBytes(Text);
            AppendToFile(strArray);

        }

        public void AppendToFile(byte[] RawBytes)
        {
            bool myLock = System.Threading.Monitor.TryEnter(writeLock, 100);


            if (myLock)
            {
                try
                {

                    using (FileStream stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                    {
                        stream.Position = stream.Length;
                        stream.Write(RawBytes, 0, RawBytes.Length);
                        stream.WriteByte(13);
                        stream.WriteByte(10);

                    }

                }
                catch (Exception ex)
                {
                    string str = string.Format("Unable to create log. Type: {0} Message: {1}\nStack:{2}", ex, ex.Message, ex.StackTrace);
                    System.Diagnostics.Debug.WriteLine(str);
                    System.Diagnostics.Debug.Flush();


                }
                finally
                {
                    System.Threading.Monitor.Exit(writeLock);


                }
            }


        }


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

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

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

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

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

        //
        // For WCF this code will never be reached
        //
        public override int Read(byte[] buffer, int offset, int count)
        {
            int c = sinkStream.Read(buffer, offset, count);
            return c;
        }

        public override long Seek(long offset, System.IO.SeekOrigin direction)
        {
            return sinkStream.Seek(offset, direction);
        }

        public override void SetLength(long length)
        {
            sinkStream.SetLength(length);
        }

        public override void Close()
        {

            sinkStream.Close();
            isClosed = true;
        }

        public override void Flush()
        {

            sinkStream.Flush();
        }

        // For streamed responses (i.e. not buffered) there will be more than one Response (but the id will match the Request)
        public override void Write(byte[] buffer, int offset, int count)
        {
            sinkStream.Write(buffer, offset, count);
            AppendToFile(String.Format("at {0} --------------------------------------------", DateTime.Now));
            AppendToFile(id);
            AppendToFile(buffer);
        }

    }
}

il doit créer un fichier log dans le chemin de log du dossier avec requête et réponse XML.

0
répondu Manish Jain 2015-05-11 06:20:13

il y a une autre façon de voir XML SOAP - custom MessageEncoder . La principale différence par rapport à IClientMessageInspector est qu'il fonctionne à un niveau inférieur, de sorte qu'il capture le contenu byte original, y compris tout xml malformé.

afin de mettre en œuvre le traçage à l'aide de cette approche, vous devez envelopper un standard textMessageEncoding avec custom message encoder comme nouvel élément de liaison et appliquer cette liaison personnalisée à votre config .

aussi, vous pouvez voir comme exemple comment je l'ai fait dans mon projet - l'habillage textMessageEncoding, de l'exploitation forestière codeur , liaison personnalisée élément et config .

0
répondu baur 2018-04-26 04:41:23