<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[XML - Alexander Development]]></title><description><![CDATA[XML - Alexander Development]]></description><link>https://alexanderdevelopment.net/</link><image><url>https://alexanderdevelopment.net/favicon.png</url><title>XML - Alexander Development</title><link>https://alexanderdevelopment.net/</link></image><generator>Ghost 1.20</generator><lastBuildDate>Fri, 24 Apr 2026 14:14:30 GMT</lastBuildDate><atom:link href="https://alexanderdevelopment.net/tag/xml/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Accessing raw SOAP requests/responses from Dynamics CRM web services in C#]]></title><description><![CDATA[<div class="kg-card-markdown"><p>One of the things I have always found frustrating about WCF is that it effectively hides the actual SOAP message XML requests and responses in web service calls. From a Dynamics CRM perspective, I can think of at least three good reasons it would be nice to be able to</p></div>]]></description><link>https://alexanderdevelopment.net/post/2013/02/20/accessing-raw-soap-requests-responses-from-dynamics-crm-web-services-in-c/</link><guid isPermaLink="false">5a5837216636a30001b97663</guid><category><![CDATA[Microsoft Dynamics CRM]]></category><category><![CDATA[CRM 2011]]></category><category><![CDATA[programming]]></category><category><![CDATA[C#]]></category><category><![CDATA[web services]]></category><category><![CDATA[XML]]></category><dc:creator><![CDATA[Lucas Alexander]]></dc:creator><pubDate>Thu, 21 Feb 2013 00:00:00 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>One of the things I have always found frustrating about WCF is that it effectively hides the actual SOAP message XML requests and responses in web service calls. From a Dynamics CRM perspective, I can think of at least three good reasons it would be nice to be able to access the raw XML generated and consumed by clients built with the SDK:</p>
<ol>
<li>Display retrieved results with XSL like I demonstrated in this client-side FetchXML example</li>
<li>Log the raw messages for QA, auditing or regulatory reasons</li>
<li>Process the XML to easily generate &quot;wrapper&quot; interfaces</li>
</ol>
<p>In this post I will show how to capture client requests and service responses for interfaces built with the CRM SDK as well as interfaces that use a WSDL-based proxy using a client message inspector.</p>
<p><strong>The message inspector class</strong></p>
<p>The easiest way to capture the actual SOAP messages is to use a client message inspector object (<a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iclientmessageinspector.aspx">IClientMessageInspector</a>). The BeforeSendRequest and AfterReceiveReply methods of the client message inspector will give you the SOAP request and response as string objects that you can process however you want. Here is a class called MyInspector that stores requests and responses in list objects called sentMessages and receivedMessages respectively <a href="https://alexanderdevelopment.net/content/images/2013/02/MyInspector.cs.txt">MyInspector.cs (1.55 kb)</a>. The original source for this code is <a href="http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/fa3f4c55-5835-43f2-892f-737b4bccb598">http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/fa3f4c55-5835-43f2-892f-737b4bccb598</a>.</p>
<p><strong>Using the message inspector</strong></p>
<p>Once you have your message inspector ready, you have to have to update the behaviors for the destination endpoint to use it. If you are using the SDK, all you have to do is instantiate a new MyInspector object and then add it to your OrganizationServiceProxy's ServiceConfiguration.CurrentServiceEndpoint behaviors. The code below contains a helper function that creates a new OrganizationServiceProxy object and adds the message inspector.</p>
<pre><code>static OrganizationServiceProxy createProxy(string orgUri, string username, string password)  
{  
ClientCredentials credentials = new ClientCredentials();  
Uri organizationUri = new Uri(orgUri);  
  
IServiceConfiguration&lt;IOrganizationService&gt; config =  
ServiceConfigurationFactory.CreateConfiguration&lt;IOrganizationService&gt;(  
organizationUri);  
  
credentials.UserName.UserName = username;  
credentials.UserName.Password = password;  
  
OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(config, credentials);  
  
MyInspector inspector = new MyInspector();  
serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(inspector);  
  
return serviceProxy;  
}
</code></pre>
<p>If you are using WSDL-based proxy, adding the message inspector is slightly different, but just as simple. As with the SDK, you first have to instantiate a new MyInspector object, but you then add it to your WCF client's Endpoint.Behaviors object. The code below shows an version of the ExecuteWhoAmI method from the CRM SDK WsdlBasedProxies sample with the message inspector added.</p>
<pre><code>private static void ExecuteWhoAmI(ClientCredentials credentials, string serviceUrl)  
{  
using (OrganizationServiceClient client = new OrganizationServiceClient(&quot;CustomBinding_IOrganizationService&quot;,  
new EndpointAddress(serviceUrl)))  
{  
ApplyCredentials(client, credentials);  
MyInspector inspector = new MyInspector();  
client.Endpoint.Behaviors.Add(inspector);  
  
OrganizationRequest request = new OrganizationRequest();  
request.RequestName = &quot;WhoAmI&quot;;  
  
OrganizationResponse response = (OrganizationResponse)client.Execute(request);  
  
foreach (KeyValuePair&lt;string, object&gt; result in response.Results)  
{  
if (&quot;UserId&quot; == result.Key)  
{  
Console.WriteLine(&quot;User ID: {0}&quot;, result.Value);  
break;  
}  
}  
}  
}
</code></pre>
<p><strong>Accessing the messages</strong></p>
<p>Once you have added the message inspector to your endpoint behaviors, you are ready to call the CRM web service and access the request and response messages. Here is an updated version of the ExecuteWhoAmI method that writes the request and response messages to the console:</p>
<pre><code>private static void ExecuteWhoAmI(ClientCredentials credentials, string serviceUrl)  
{  
using (OrganizationServiceClient client = new OrganizationServiceClient(&quot;CustomBinding_IOrganizationService&quot;,  
new EndpointAddress(serviceUrl)))  
{  
ApplyCredentials(client, credentials);  
MyInspector inspector = new MyInspector();  
client.Endpoint.Behaviors.Add(inspector);  
  
OrganizationRequest request = new OrganizationRequest();  
request.RequestName = &quot;WhoAmI&quot;;  
  
OrganizationResponse response = (OrganizationResponse)client.Execute(request);  
  
foreach (KeyValuePair&lt;string, object&gt; result in response.Results)  
{  
if (&quot;UserId&quot; == result.Key)  
{  
Console.WriteLine(&quot;User ID: {0}&quot;, result.Value);  
break;  
}  
}  
  
Console.WriteLine(&quot;****REQUEST****&quot;);  
foreach (string sent in inspector.sentMessages)  
{  
Console.WriteLine(sent);  
Console.WriteLine();  
  
}  
  
Console.WriteLine(&quot;****RESPONSE****&quot;);  
foreach (string received in inspector.receivedMessages)  
{  
Console.WriteLine(received);  
Console.WriteLine();  
}  
Console.ReadLine();  
}  
}
</code></pre>
</div>]]></content:encoded></item><item><title><![CDATA[Misadventures with CRM 2011 web services and ADFS]]></title><description><![CDATA[<div class="kg-card-markdown"><p>I think the Dynamics CRM 2011 SDK is swell for interoperability, but I wanted to get a closer look at how the actual web service calls work, so I decided to access the sandbox CRM instance my company provides using a WSDL-based proxy as described <a href="http://msdn.microsoft.com/en-us/library/gg509052.aspx">here</a>. Because the SDK has</p></div>]]></description><link>https://alexanderdevelopment.net/post/2013/02/16/misadventures-with-crm-2011-web-services-and-adfs/</link><guid isPermaLink="false">5a5837216636a30001b9766a</guid><category><![CDATA[Microsoft Dynamics CRM]]></category><category><![CDATA[CRM 2011]]></category><category><![CDATA[programming]]></category><category><![CDATA[C#]]></category><category><![CDATA[web services]]></category><category><![CDATA[XML]]></category><dc:creator><![CDATA[Lucas Alexander]]></dc:creator><pubDate>Sun, 17 Feb 2013 00:00:00 GMT</pubDate><content:encoded><![CDATA[<div class="kg-card-markdown"><p>I think the Dynamics CRM 2011 SDK is swell for interoperability, but I wanted to get a closer look at how the actual web service calls work, so I decided to access the sandbox CRM instance my company provides using a WSDL-based proxy as described <a href="http://msdn.microsoft.com/en-us/library/gg509052.aspx">here</a>. Because the SDK has several examples for connecting to CRM instances using different kinds of authentication in the SDK\SampleCode\CS\WsdlBasedProxies directory, I figured this would be a piece of cake. As it turns out, I was wrong.</p>
<p><em>Disclaimer: before asking anyone read through to the end of this post, let me say I think the problem I ran into may be fairly specific to my organization's ADFS setup because despite a lot of web searches, I couldn't find anything that specifically addressed my issue from a Dynamics CRM perspective. On the other hand, if you are having the same problem I did, maybe this post will save you some time.</em></p>
<p>Because my CRM sandbox instance is an Internet-facing (IFD) deployment, I looked at the ifd project in the SDK's wsdlbasedproxies solution and followed the setup instructions. I ran into a problem almost immediately. After creating service references for the Discovery and Organization services, the next instruction is:</p>
<blockquote>
<p>In the &quot;<binding name="CustomBinding_IOrganizationService">&quot; node, locate the &quot;&lt;issuer ...&gt;&quot; node. This node allows the user to specify which Issuer should be used when issuing a token. The various STS endpoints will be present in the commented out &quot;alternativeIssuedTokenParameters&quot; node. In my example, UserNameMixed is used. In order to use UserNameMixed, the &quot;binding&quot; and &quot;bindingConfiguration&quot; attributes need to be updated to match the node in &quot;alternativeIssuedTokenParameters&quot;. The easiest way to find this endpoint is to search for &quot;<a href="https://adfs.contoso.com:555/adfs/services/trust/13/usernamemixed">https://adfs.contoso.com:555/adfs/services/trust/13/usernamemixed</a>&quot;. In the generated configuration file, you'll find: <issuer address="https://adfs.contoso.com:555/adfs/services/trust/13/usernamemixed" bindingconfiguration="https://adfs.contoso.com:555/adfs/services/trust/13/usernamemixed" binding="ws2007HttpBinding"> Copy this node and replace the current issuer node in the &quot;<binding name="CustomBinding_IOrganizationService">&quot; node.</binding></issuer></binding></p>
</blockquote>
<p>Well, in my app.config file, there was no alternativeIssuedTokenParameters node. All I had was these two elements in my CustomBinding_IOrganizationService and CustomBinding_IDiscoveryService bindings:</p>
<pre><code>&lt;issuer address=&quot;http://schemas.microsoft.com/2005/12/ServiceModel/Addressing/Anonymous&quot; /&gt;  
&lt;issuerMetadata address=&quot;https://ADFS.SOMEDOMAIN.COM/adfs/services/trust/mex&quot; /&gt;
</code></pre>
<p>I figured what the heck, let's try to run the sample in debug mode anyway and see if it works. Spoiler alert: it didn't. Instead of connecting to CRM, I got a Windows CardSpace (never heard of it before) screen pop up asking me if I wanted to send a card to the site. Seeing as the SDK readme doc had made of mention of CardSpace, I figured something must be misconfigured, so I closed the window and stopped debugging.</p>
<p>It took me a while to figure it out (I'm a developer, not a networking guy), but I finally realized that my WCF client knew it should be using a token from the SOMEDOMAIN.COM STS to talk to CRM, but it didn't know how to get one. After some fruitless searching, I stumbled upon a post by the MCS UK dev team called &quot;<a href="http://blogs.msdn.com/b/mcsuksoldev/archive/2011/08/17/federated-security-how-to-setup-and-call-a-wcf-service-secured-by-adfs-2-0.aspx">Federated Security: How to setup and call a WCF service secured by ADFS 2.0.</a>&quot; At first I looked at programmatically getting a token, but then I decided it would be much simpler to take the config-based approach described in this MSDN tutorial: <a href="http://msdn.microsoft.com/en-us/gg557876">http://msdn.microsoft.com/en-us/gg557876</a>. Also, the config-based approach is what should have been happening in the SDK sample anyway.</p>
<p>To get the issuer element of my bindings right, I first created a service reference for the address in the issuerMetadata element. As soon as I did, my app.config file was updated with lots of binding and endpoints that looked like what was described in the SDK sample setup file, so I figured I must be on the right track.</p>
<p>Knowing that my sandbox CRM instance used the &quot;/adfs/services/trust/13/username&quot; endpoint for getting a token from the ADFS STS (thanks to watching Fiddler while a desktop application that uses the SDK connected to my CRM instance), I searched in the updated app.config file for that string, and I found this element:</p>
<pre><code>&lt;endpoint address=&quot;http://ADFS.SOMEDOMAIN.COM/adfs/services/trust/13/username&quot;  
binding=&quot;ws2007HttpBinding&quot; bindingConfiguration=&quot;UserNameWSTrustBinding_IWSTrust13Async&quot;  
contract=&quot;STS.IWSTrust13Async&quot; name=&quot;UserNameWSTrustBinding_IWSTrust13Async&quot;&gt;  
&lt;identity&gt;  
&lt;certificate encodedValue=&quot;REALLY_LONG_CERTIFICATE_STRING...&quot; /&gt;  
&lt;/identity&gt;  
&lt;/endpoint&gt;
</code></pre>
<p>Next, I commented out the existing issuer and issuerMetadata elements in my CRM service bindings and replaced them with the address, binding, binding configuration and identity details from the STS endpoint like so:</p>
<pre><code>&lt;issuer address=&quot;http://ADFS.SOMEDOMAIN.COM/adfs/services/trust/13/username&quot; binding=&quot;ws2007HttpBinding&quot; bindingConfiguration=&quot;UserNameWSTrustBinding_IWSTrust13Async&quot; &gt;  
&lt;identity&gt;  
&lt;certificate encodedValue=&quot;REALLY_LONG_CERTIFICATE_STRING...&quot; /&gt;  
&lt;/identity&gt;  
&lt;/issuer&gt;
</code></pre>
<p>After that, I ran the sample project in debug mode, and it worked perfectly.</p>
<p><strong>Why did this happen?</strong></p>
<p>I will readily admit I don't understand the ins and outs of ADFS. I get the point of it and the basics of how it works, but I certainly don't know why the configuration of my CRM instance would lead to these results. All I can say at this point is that I'm glad I've got it working, and I'll know what to do in the future if a problem like this ever comes up again.</p>
</div>]]></content:encoded></item></channel></rss>