Last week I wrote a post that showed how to retrive the raw SOAP response from a Dynamics CRM query in C#, but I didn't show how to do anything useful with it. In today's post I will show a practical example of how to execute a FetchXML request against a Dynamics CRM instance, capture the raw SOAP response and transform it with XSLT for display in an ASPX page. For demonstration purposes, I will be using the same query and XSL as I used in my "Displaying FetchXML results with XSLT on the client side in a Dynamics CRM 2011 web resource" post.
In this example I am using a WSDL-based proxy instead of the CRM SDK, but all of the code I am sharing can be easily modified to work with the SDK instead.
My ASPX page has five controls:
- xmlTextBox textbox to input the FetchXML query
- xslTextBox textbox to input the XSL for the transformation
- executeButton button to retrieve and transform the data
- resultsTextBox textbox to show the SOAP response
- resultsLiteral literal to show the transformed data
When the executeButton button is clicked, the following steps take place:
- Set up a WCF client connection to the CRM OrganizationService (with client message inspector as described in my last post)
- Retrieve the results for the supplied FetchXML query
- Show the SOAP response
- Transform the SOAP response using the supplied XSL
- Show the transformed results
Here's the code:
/// <summary>
/// executes retrieve and transform functionality
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void executeButton_Click(object sender, EventArgs e)
{
OrganizationServiceClient client = SetupClient();
string results = RetrieveData(this.xmlTextBox.Text, client);
string xsl = this.xslTextBox.Text;
this.resultsTextBox.Text = results;
this.resultsLiteral.Text = DoTransform(results, xsl);
}
/// <summary>
/// instantiates an OrganizationServiceClient object for the username/password/organization service specified as constants
/// </summary>
/// <returns></returns>
private OrganizationServiceClient SetupClient()
{
ClientCredentials credentials = new ClientCredentials();
credentials.UserName.UserName = UserName; //UserName is a constant
credentials.UserName.Password = UserPassword; //UserPassword is a constant
OrganizationServiceClient client = new OrganizationServiceClient("CustomBinding_IOrganizationService",
new EndpointAddress(OrganizationServiceUrl)); //OrganizationServiceUrl is a constant
client.ClientCredentials.UserName.UserName = credentials.UserName.UserName;
client.ClientCredentials.UserName.Password = credentials.UserName.Password;
return client;
}
/// <summary>
/// executes a fetchxml query with a given org service client and returns the SOAP response as a string
/// </summary>
/// <param name="fetchXml">query</param>
/// <param name="client">client</param>
/// <returns>response</returns>
string RetrieveData(string fetchXml, OrganizationServiceClient client)
{
string response = "";
//set up a client message inspector for the query
//see http://alexanderdevelopment.net/post/2013/02/21/Accessing-raw-SOAP-requests-responses-from-Dynamics-CRM-web-services-in-C.aspx
MyInspector inspector = new MyInspector();
client.Endpoint.Behaviors.Add(inspector);
//build the fetchxml
FetchExpression fetch = new FetchExpression();
fetch.Query = fetchXml;
EntityCollection entities = client.RetrieveMultiple(fetch);
//if there is a captured response
if (inspector.receivedMessages.Count == 1)
{
response = inspector.receivedMessages[0];
}
//return it
return response;
}
/// <summary>
/// transforms supplied results xml with supplied xsl
/// </summary>
/// <param name="results">input xml</param>
/// <param name="xsl">xsl style sheet</param>
/// <returns>transformed output</returns>
string DoTransform(string results, string xsl)
{
//create an xmldocument from the input xml
System.Xml.XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(results);
//create an xmldocument from the input xsl
System.Xml.XmlDocument xslDoc = new XmlDocument();
xslDoc.LoadXml(xsl);
//load a compiled xsl transform object from the xsl document
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load(xslDoc);
//prepare stringwriter and xmlwriter get string output from transformation
StringWriter sw = new StringWriter();
XmlWriter xwriter = XmlWriter.Create(sw);
//execute the transformation
transform.Transform(xmlDoc, xwriter);
//return the output
string output = sw.ToString();
return output;
}
My .aspx and .aspx.cs files are attached here for reference.