Tuesday, February 14, 2012

Submit a Bulk Duplicate Detection Job in Microsoft Dynamics CRM 2011 using C# or Jscript

This illustration shows how to submit a bulk duplicate detection job in Microsoft Dynamics CRM 2011 with BulkDetectDuplicatesRequest.  This example will be given in Jscript (SOAP) and in C# (.NET).


NOTES: 

- You can schedule the job at regular intervals if desired using this request.  See the following link for details. http://msdn.microsoft.com/en-us/library/cc189846.aspx


Ok, here is what the code looks like!
First in C#:

BulkDetectDuplicatesRequest req = new BulkDetectDuplicatesRequest();
//send email to these receipients after job completes
req.ToRecipients = new Guid[] { new Guid("6E219F51-0310-4C4D-8C60-1C524E2BA7B3") };
//add cc recipients to the email here if desired
req.CCRecipients = new Guid[0];
req.JobName = "testbulkdeletejob";
req.SendEmailNotification = true;

req.RecurrencePattern = "";
//example of recurrence pattern 
//int interval = 30;
//string pattern = String.Format(System.Globalization.CultureInfo.InvariantCulture, "FREQ=DAILY;INTERVAL={0};", interval);
//req.RecurrencePattern = pattern;
req.Query = new QueryExpression()
{
    EntityName = "account",
    ColumnSet = new ColumnSet(true),
    Criteria = new FilterExpression
    {
        FilterOperator = LogicalOperator.And,
        Conditions = 
        {
      
            new ConditionExpression
            {
                AttributeName = "name",
                Operator = ConditionOperator.Equal,
                Values = { "test account in code" }
            }
        }
    }
};
 //Guid of email template for email that will be sent (must be a system job email template)
req.TemplateId = new Guid("D1F0639F-2057-E111-B314-1CC1DEF1353B");

BulkDetectDuplicatesResponse resp = (BulkDetectDuplicatesResponse)service.Execute(req);


If you need help instantiating a service object in .NET within a plugin check out this post:
http://mileyja.blogspot.com/2011/04/instantiating-service-object-within.html


Now here is the Jscript nicely formatted by the CRM 2011 SOAP formatter. Available at: http://crm2011soap.codeplex.com/

Now in Jscript

This example is asynchronous, if you want to learn how to make JScript SOAP calls synchronously please visit this posthttp://mileyja.blogspot.com/2011/07/using-jscript-to-access-soap-web.html

if (typeof (SDK) == "undefined")
   { SDK = { __namespace: true }; }
       //This will establish a more unique namespace for functions in this library. This will reduce the 
       // potential for functions to be overwritten due to a duplicate name when the library is loaded.
       SDK.SAMPLES = {
           _getServerUrl: function () {
               ///<summary>
               /// Returns the URL for the SOAP endpoint using the context information available in the form
               /// or HTML Web resource.
               ///</summary>
               var ServicePath = "/XRMServices/2011/Organization.svc/web";
               var serverUrl = "";
               if (typeof GetGlobalContext == "function") {
                   var context = GetGlobalContext();
                   serverUrl = context.getServerUrl();
               }
               else {
                   if (typeof Xrm.Page.context == "object") {
                         serverUrl = Xrm.Page.context.getServerUrl();
                   }
                   else
                   { throw new Error("Unable to access the server URL"); }
                   }
                  if (serverUrl.match(/\/$/)) {
                       serverUrl = serverUrl.substring(0, serverUrl.length - 1);
                   } 
                   return serverUrl + ServicePath;
               }, 
           BulkDetectDuplicatesRequest: function () {
               var requestMain = ""
               requestMain += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
               requestMain += "  <s:Body>";
               requestMain += "    <Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
               requestMain += "      <request i:type=\"b:BulkDetectDuplicatesRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">";
               requestMain += "        <a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>Query</c:key>";
               requestMain += "            <c:value i:type=\"a:QueryExpression\">";
               requestMain += "              <a:ColumnSet>";
               requestMain += "                <a:AllColumns>true</a:AllColumns>";
               requestMain += "                <a:Columns xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\" />";
               requestMain += "              </a:ColumnSet>";
               requestMain += "              <a:Criteria>";
               requestMain += "                <a:Conditions>";
               requestMain += "                  <a:ConditionExpression>";
               requestMain += "                    <a:AttributeName>name</a:AttributeName>";
               requestMain += "                    <a:Operator>Equal</a:Operator>";
               requestMain += "                    <a:Values xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">";
               requestMain += "                      <d:anyType i:type=\"e:string\" xmlns:e=\"http://www.w3.org/2001/XMLSchema\">test account in code</d:anyType>";
               requestMain += "                    </a:Values>";
               requestMain += "                  </a:ConditionExpression>";
               requestMain += "                </a:Conditions>";
               requestMain += "                <a:FilterOperator>And</a:FilterOperator>";
               requestMain += "                <a:Filters />";
               requestMain += "              </a:Criteria>";
               requestMain += "              <a:Distinct>false</a:Distinct>";
               requestMain += "              <a:EntityName>account</a:EntityName>";
               requestMain += "              <a:LinkEntities />";
               requestMain += "              <a:Orders />";
               requestMain += "              <a:PageInfo>";
               requestMain += "                <a:Count>0</a:Count>";
               requestMain += "                <a:PageNumber>0</a:PageNumber>";
               requestMain += "                <a:PagingCookie i:nil=\"true\" />";
               requestMain += "                <a:ReturnTotalRecordCount>false</a:ReturnTotalRecordCount>";
               requestMain += "              </a:PageInfo>";
               requestMain += "              <a:NoLock>false</a:NoLock>";
               requestMain += "            </c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>JobName</c:key>";
               requestMain += "            <c:value i:type=\"d:string\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\">testbulkdeletejob</c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>SendEmailNotification</c:key>";
               requestMain += "            <c:value i:type=\"d:boolean\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\">true</c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>TemplateId</c:key>";
               requestMain += "            <c:value i:type=\"d:guid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/\">d1f0639f-2057-e111-b314-1cc1def1353b</c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>ToRecipients</c:key>";
               requestMain += "            <c:value i:type=\"d:ArrayOfguid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">";
               requestMain += "              <d:guid>6e219f51-0310-4c4d-8c60-1c524e2ba7b3</d:guid>";
               requestMain += "            </c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>CCRecipients</c:key>";
               requestMain += "            <c:value i:type=\"d:ArrayOfguid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\" />";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>RecurrencePattern</c:key>";
               requestMain += "            <c:value i:type=\"d:string\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\" />";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>RecurrenceStartTime</c:key>";
               requestMain += "            <c:value i:type=\"d:dateTime\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\">0001-01-01T00:00:00</c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "        </a:Parameters>";
               requestMain += "        <a:RequestId i:nil=\"true\" />";
               requestMain += "        <a:RequestName>BulkDetectDuplicates</a:RequestName>";
               requestMain += "      </request>";
               requestMain += "    </Execute>";
               requestMain += "  </s:Body>";
               requestMain += "</s:Envelope>";
               var req = new XMLHttpRequest();
               req.open("POST", SDK.SAMPLES._getServerUrl(), true)
               req.setRequestHeader("Accept", "application/xml, text/xml, */*");
               req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
               req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
               var successCallback = null;
               var errorCallback = null;
               req.onreadystatechange = function () { SDK.SAMPLES.BulkDetectDuplicatesResponse(req, successCallback, errorCallback); };
               req.send(requestMain);
           },
       BulkDetectDuplicatesResponse: function (req, successCallback, errorCallback) {
               ///<summary>
               /// Recieves the assign response
               ///</summary>
               ///<param name="req" Type="XMLHttpRequest">
               /// The XMLHttpRequest response
               ///</param>
               ///<param name="successCallback" Type="Function">
               /// The function to perform when an successfult response is returned.
               /// For this message no data is returned so a success callback is not really necessary.
               ///</param>
               ///<param name="errorCallback" Type="Function">
               /// The function to perform when an error is returned.
               /// This function accepts a JScript error returned by the _getError function
               ///</param>
               if (req.readyState == 4) {
               if (req.status == 200) {
               if (successCallback != null)
               { successCallback(); }
               }
               else {
                   errorCallback(SDK.SAMPLES._getError(req.responseXML));
               }
           }
       },
       _getError: function (faultXml) {
           ///<summary>
           /// Parses the WCF fault returned in the event of an error.
           ///</summary>
           ///<param name="faultXml" Type="XML">
           /// The responseXML property of the XMLHttpRequest response.
           ///</param>
           var errorMessage = "Unknown Error (Unable to parse the fault)";
           if (typeof faultXml == "object") {
               try {
                   var bodyNode = faultXml.firstChild.firstChild;
                   //Retrieve the fault node
                   for (var i = 0; i < bodyNode.childNodes.length; i++) {
                       var node = bodyNode.childNodes[i];
                       //NOTE: This comparison does not handle the case where the XML namespace changes
                       if ("s:Fault" == node.nodeName) {
                       for (var j = 0; j < node.childNodes.length; j++) {
                           var faultStringNode = node.childNodes[j];
                           if ("faultstring" == faultStringNode.nodeName) {
                               errorMessage = faultStringNode.text;
                               break;
                           }
                       }
                       break;
                   }
               }
           }
           catch (e) { };
        }
        return new Error(errorMessage);
     },
 __namespace: true
};




To understand how to parse the response please review my post on using the DOM parser.
Now you can call the SDK.SAMPLES.BulkDetectDuplicatesRequest function from your form jscript handler.

Thats all there is to it!
-

Monday, February 13, 2012

Submit a Bulk Delete Job in Microsoft Dynamics CRM 2011 using C# or Jscript

This illustration shows how to submit a bulk delete job in Microsoft Dynamics CRM 2011 with BulkDeleteRequest.  This example will be given in Jscript (SOAP) and in C# (.NET).

NOTES: 

- You can schedule the job at regular intervals if desired using this request.  See the following link for details. http://msdn.microsoft.com/en-us/library/cc189846.aspx

- You can also define a start date and time for the job to occur.

- Lastly, this does not really act as a bulk delete request in the same sense as a bulk insert in SQL.  It submits an asynchronous job to the server that runs in the background but deletes the records one by one.  You will not really gain performance by this call versus a normal mass delete, but at least you won't have to babysit it.

Ok, here is what the code looks like!
First in C#:
BulkDeleteRequest req = new BulkDeleteRequest();
//send email to these receipients after job completes
req.ToRecipients = new Guid[] { new Guid("6E219F51-0310-4C4D-8C60-1C524E2BA7B3") };
//add cc recipients to the email here if desired
req.CCRecipients = new Guid[0];
req.JobName = "testbulkdeletejob";
req.SendEmailNotification = true;

req.RecurrencePattern = "";
//example of recurrence pattern 
   //int interval = 30;
   //string pattern = String.Format(System.Globalization.CultureInfo.InvariantCulture, "FREQ=DAILY;INTERVAL={0};", interval);
   //req.RecurrencePattern = pattern;
req.QuerySet = new QueryExpression[]
{
   new QueryExpression()
   {
       EntityName = "account",
       ColumnSet = new ColumnSet(true),
       Criteria = new FilterExpression
       {
           FilterOperator = LogicalOperator.And,
           Conditions = 
          {
              
              new ConditionExpression
              {
                  AttributeName = "name",
                  Operator = ConditionOperator.Equal,
                  Values = { "test account in code" }
              }
          }
       }
   }
};
BulkDeleteResponse resp = (BulkDeleteResponse)service.Execute(req);


If you need help instantiating a service object in .NET within a plugin check out this post:
http://mileyja.blogspot.com/2011/04/instantiating-service-object-within.html

Now here is the Jscript nicely formatted by the CRM 2011 SOAP formatter. Available at: http://crm2011soap.codeplex.com/

Now in Jscript


This example is asynchronous, if you want to learn how to make JScript SOAP calls synchronously please visit this posthttp://mileyja.blogspot.com/2011/07/using-jscript-to-access-soap-web.html


if (typeof (SDK) == "undefined")
   { SDK = { __namespace: true }; }
       //This will establish a more unique namespace for functions in this library. This will reduce the 
       // potential for functions to be overwritten due to a duplicate name when the library is loaded.
       SDK.SAMPLES = {
           _getServerUrl: function () {
               ///<summary>
               /// Returns the URL for the SOAP endpoint using the context information available in the form
               /// or HTML Web resource.
               ///</summary>
               var ServicePath = "/XRMServices/2011/Organization.svc/web";
               var serverUrl = "";
               if (typeof GetGlobalContext == "function") {
                   var context = GetGlobalContext();
                   serverUrl = context.getServerUrl();
               }
               else {
                   if (typeof Xrm.Page.context == "object") {
                         serverUrl = Xrm.Page.context.getServerUrl();
                   }
                   else
                   { throw new Error("Unable to access the server URL"); }
                   }
                  if (serverUrl.match(/\/$/)) {
                       serverUrl = serverUrl.substring(0, serverUrl.length - 1);
                   } 
                   return serverUrl + ServicePath;
               }, 
           BulkDeleteRequest: function () {
               var requestMain = ""
               requestMain += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
               requestMain += "  <s:Body>";
               requestMain += "    <Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
               requestMain += "      <request i:type=\"b:BulkDeleteRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">";
               requestMain += "        <a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>QuerySet</c:key>";
               requestMain += "            <c:value i:type=\"a:ArrayOfQueryExpression\">";
               requestMain += "              <a:QueryExpression>";
               requestMain += "                <a:ColumnSet>";
               requestMain += "                  <a:AllColumns>true</a:AllColumns>";
               requestMain += "                  <a:Columns xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\" />";
               requestMain += "                </a:ColumnSet>";
               requestMain += "                <a:Criteria>";
               requestMain += "                  <a:Conditions>";
               requestMain += "                    <a:ConditionExpression>";
               requestMain += "                      <a:AttributeName>name</a:AttributeName>";
               requestMain += "                      <a:Operator>Equal</a:Operator>";
               requestMain += "                      <a:Values xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">";
               requestMain += "                        <d:anyType i:type=\"e:string\" xmlns:e=\"http://www.w3.org/2001/XMLSchema\">test account in code</d:anyType>";
               requestMain += "                      </a:Values>";
               requestMain += "                    </a:ConditionExpression>";
               requestMain += "                  </a:Conditions>";
               requestMain += "                  <a:FilterOperator>And</a:FilterOperator>";
               requestMain += "                  <a:Filters />";
               requestMain += "                </a:Criteria>";
               requestMain += "                <a:Distinct>false</a:Distinct>";
               requestMain += "                <a:EntityName>account</a:EntityName>";
               requestMain += "                <a:LinkEntities />";
               requestMain += "                <a:Orders />";
               requestMain += "                <a:PageInfo>";
               requestMain += "                  <a:Count>0</a:Count>";
               requestMain += "                  <a:PageNumber>0</a:PageNumber>";
               requestMain += "                  <a:PagingCookie i:nil=\"true\" />";
               requestMain += "                  <a:ReturnTotalRecordCount>false</a:ReturnTotalRecordCount>";
               requestMain += "                </a:PageInfo>";
               requestMain += "                <a:NoLock>false</a:NoLock>";
               requestMain += "              </a:QueryExpression>";
               requestMain += "            </c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>JobName</c:key>";
               requestMain += "            <c:value i:type=\"d:string\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\">testbulkdeletejob</c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>SendEmailNotification</c:key>";
               requestMain += "            <c:value i:type=\"d:boolean\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\">true</c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>ToRecipients</c:key>";
               requestMain += "            <c:value i:type=\"d:ArrayOfguid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">";
               requestMain += "              <d:guid>6e219f51-0310-4c4d-8c60-1c524e2ba7b3</d:guid>";
               requestMain += "            </c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>CCRecipients</c:key>";
               requestMain += "            <c:value i:type=\"d:ArrayOfguid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\" />";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>RecurrencePattern</c:key>";
               requestMain += "            <c:value i:type=\"d:string\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\" />";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>StartDateTime</c:key>";
               requestMain += "            <c:value i:type=\"d:dateTime\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\">0001-01-01T00:00:00</c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "        </a:Parameters>";
               requestMain += "        <a:RequestId i:nil=\"true\" />";
               requestMain += "        <a:RequestName>BulkDelete</a:RequestName>";
               requestMain += "      </request>";
               requestMain += "    </Execute>";
               requestMain += "  </s:Body>";
               requestMain += "</s:Envelope>";
               var req = new XMLHttpRequest();
               req.open("POST", SDK.SAMPLES._getServerUrl(), true)
               req.setRequestHeader("Accept", "application/xml, text/xml, */*");
               req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
               req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
               var successCallback = null;
               var errorCallback = null;
               req.onreadystatechange = function () { SDK.SAMPLES.BulkDeleteResponse(req, successCallback, errorCallback); };
               req.send(requestMain);
           },
       BulkDeleteResponse: function (req, successCallback, errorCallback) {
               ///<summary>
               /// Recieves the assign response
               ///</summary>
               ///<param name="req" Type="XMLHttpRequest">
               /// The XMLHttpRequest response
               ///</param>
               ///<param name="successCallback" Type="Function">
               /// The function to perform when an successfult response is returned.
               /// For this message no data is returned so a success callback is not really necessary.
               ///</param>
               ///<param name="errorCallback" Type="Function">
               /// The function to perform when an error is returned.
               /// This function accepts a JScript error returned by the _getError function
               ///</param>
               if (req.readyState == 4) {
               if (req.status == 200) {
               if (successCallback != null)
               { successCallback(); }
               }
               else {
                   errorCallback(SDK.SAMPLES._getError(req.responseXML));
               }
           }
       },
       _getError: function (faultXml) {
           ///<summary>
           /// Parses the WCF fault returned in the event of an error.
           ///</summary>
           ///<param name="faultXml" Type="XML">
           /// The responseXML property of the XMLHttpRequest response.
           ///</param>
           var errorMessage = "Unknown Error (Unable to parse the fault)";
           if (typeof faultXml == "object") {
               try {
                   var bodyNode = faultXml.firstChild.firstChild;
                   //Retrieve the fault node
                   for (var i = 0; i < bodyNode.childNodes.length; i++) {
                       var node = bodyNode.childNodes[i];
                       //NOTE: This comparison does not handle the case where the XML namespace changes
                       if ("s:Fault" == node.nodeName) {
                       for (var j = 0; j < node.childNodes.length; j++) {
                           var faultStringNode = node.childNodes[j];
                           if ("faultstring" == faultStringNode.nodeName) {
                               errorMessage = faultStringNode.text;
                               break;
                           }
                       }
                       break;
                   }
               }
           }
           catch (e) { };
        }
        return new Error(errorMessage);
     },
 __namespace: true
};




To understand how to parse the response please review my post on using the DOM parser.
Now you can call the SDK.SAMPLES.BulkDeleteRequest function from your form jscript handler.

Thats all there is to it!
-

Friday, February 10, 2012

You Got Questions, We got Answers!

I get a lot of questions directed to my personal email through my about.me account.  I like to help people answer their questions, but if it's not a direct inquiry that pertains directly to a post on my blog, I would ask that you direct your questions to the official Microsoft forums.    

This is a couple of good reasons for this:

  • You get more exposure!  More eyes are always better in these situations; because, let's face it, I don't know everything, and sometimes I just don't have time.  More people seeing your question means a better chance at getting an answer.
  • Other people might have the same question!  If the question is answered in the forum it can turn up easily in a Google or Bing search or people searching the forum.  This helps more people.
Here are the main forums for CRM:

General CRM Questions:

CRM Development Related Questions:

CRM Deployment Related Questions:

These three forums are general access and heavily used so you don't need to be a partner to use them and you can be pretty sure that some very smart people will see them.

Thanks!

Thursday, February 9, 2012

Send an Email Asynchronously in Microsoft Dynamics CRM 2011 using C# or Jscript

This illustration shows how to send an email asynchronously in Microsoft Dynamics CRM 2011 with BackgroundSendEmailRequest.  This example will be given in Jscript (SOAP) and in C# (.NET).

NOTE: Two days ago I covered creating the email activity in CRM in code (a prerequisite to today's tutorial).  Check it out if you are having trouble creating the entity: http://mileyja.blogspot.com/2012/02/create-email-activity-in-microsoft.html

Additionally, it's interesting to note that you can use a QueryExpression to filter on what non-sent email it will send.  It allows you to send more than one at once.

Ok, here is what the code looks like!
First in C#:
BackgroundSendEmailRequest req = new BackgroundSendEmailRequest();   
QueryExpression query = new QueryExpression()
{
    EntityName = "email",
    ColumnSet = new ColumnSet(true),
    Criteria = new FilterExpression
    {
        FilterOperator = LogicalOperator.And,
        Conditions = 
        {
            new ConditionExpression
            {
                AttributeName = "regardingobjectid",
                Operator = ConditionOperator.Equal,
                Values = { "AC946D36-3E41-E111-9D05-0050569838D6" }
            }
        }
    }
};

req.Query = query;
service.Execute(req);


If you need help instantiating a service object in .NET within a plugin check out this post:
http://mileyja.blogspot.com/2011/04/instantiating-service-object-within.html

Now here is the Jscript nicely formatted by the CRM 2011 SOAP formatter. Available at: http://crm2011soap.codeplex.com/

Now in Jscript


This example is asynchronous, if you want to learn how to make JScript SOAP calls synchronously please visit this posthttp://mileyja.blogspot.com/2011/07/using-jscript-to-access-soap-web.html


if (typeof (SDK) == "undefined")
   { SDK = { __namespace: true }; }
       //This will establish a more unique namespace for functions in this library. This will reduce the 
       // potential for functions to be overwritten due to a duplicate name when the library is loaded.
       SDK.SAMPLES = {
           _getServerUrl: function () {
               ///<summary>
               /// Returns the URL for the SOAP endpoint using the context information available in the form
               /// or HTML Web resource.
               ///</summary>
               var ServicePath = "/XRMServices/2011/Organization.svc/web";
               var serverUrl = "";
               if (typeof GetGlobalContext == "function") {
                   var context = GetGlobalContext();
                   serverUrl = context.getServerUrl();
               }
               else {
                   if (typeof Xrm.Page.context == "object") {
                         serverUrl = Xrm.Page.context.getServerUrl();
                   }
                   else
                   { throw new Error("Unable to access the server URL"); }
                   }
                  if (serverUrl.match(/\/$/)) {
                       serverUrl = serverUrl.substring(0, serverUrl.length - 1);
                   } 
                   return serverUrl + ServicePath;
               }, 
           BackgroundSendEmailRequest: function () {
               var requestMain = ""
               requestMain += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
               requestMain += "  <s:Body>";
               requestMain += "    <Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
               requestMain += "      <request i:type=\"b:BackgroundSendEmailRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">";
               requestMain += "        <a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>Query</c:key>";
               requestMain += "            <c:value i:type=\"a:QueryExpression\">";
               requestMain += "              <a:ColumnSet>";
               requestMain += "                <a:AllColumns>true</a:AllColumns>";
               requestMain += "                <a:Columns xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\" />";
               requestMain += "              </a:ColumnSet>";
               requestMain += "              <a:Criteria>";
               requestMain += "                <a:Conditions>";
               requestMain += "                  <a:ConditionExpression>";
               requestMain += "                    <a:AttributeName>regardingobjectid</a:AttributeName>";
               requestMain += "                    <a:Operator>Equal</a:Operator>";
               requestMain += "                    <a:Values xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/Arrays\">";
               requestMain += "                      <d:anyType i:type=\"e:string\" xmlns:e=\"http://www.w3.org/2001/XMLSchema\">AC946D36-3E41-E111-9D05-0050569838D6</d:anyType>";
               requestMain += "                    </a:Values>";
               requestMain += "                  </a:ConditionExpression>";
               requestMain += "                </a:Conditions>";
               requestMain += "                <a:FilterOperator>And</a:FilterOperator>";
               requestMain += "                <a:Filters />";
               requestMain += "              </a:Criteria>";
               requestMain += "              <a:Distinct>false</a:Distinct>";
               requestMain += "              <a:EntityName>email</a:EntityName>";
               requestMain += "              <a:LinkEntities />";
               requestMain += "              <a:Orders />";
               requestMain += "              <a:PageInfo>";
               requestMain += "                <a:Count>0</a:Count>";
               requestMain += "                <a:PageNumber>0</a:PageNumber>";
               requestMain += "                <a:PagingCookie i:nil=\"true\" />";
               requestMain += "                <a:ReturnTotalRecordCount>false</a:ReturnTotalRecordCount>";
               requestMain += "              </a:PageInfo>";
               requestMain += "              <a:NoLock>false</a:NoLock>";
               requestMain += "            </c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "        </a:Parameters>";
               requestMain += "        <a:RequestId i:nil=\"true\" />";
               requestMain += "        <a:RequestName>BackgroundSendEmail</a:RequestName>";
               requestMain += "      </request>";
               requestMain += "    </Execute>";
               requestMain += "  </s:Body>";
               requestMain += "</s:Envelope>";
               var req = new XMLHttpRequest();
               req.open("POST", SDK.SAMPLES._getServerUrl(), true)
               req.setRequestHeader("Accept", "application/xml, text/xml, */*");
               req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
               req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
               var successCallback = null;
               var errorCallback = null;
               req.onreadystatechange = function () { SDK.SAMPLES.BackgroundSendEmailResponse(req, successCallback, errorCallback); };
               req.send(requestMain);
           },
       BackgroundSendEmailResponse: function (req, successCallback, errorCallback) {
               ///<summary>
               /// Recieves the assign response
               ///</summary>
               ///<param name="req" Type="XMLHttpRequest">
               /// The XMLHttpRequest response
               ///</param>
               ///<param name="successCallback" Type="Function">
               /// The function to perform when an successfult response is returned.
               /// For this message no data is returned so a success callback is not really necessary.
               ///</param>
               ///<param name="errorCallback" Type="Function">
               /// The function to perform when an error is returned.
               /// This function accepts a JScript error returned by the _getError function
               ///</param>
               if (req.readyState == 4) {
               if (req.status == 200) {
               if (successCallback != null)
               { successCallback(); }
               }
               else {
                   errorCallback(SDK.SAMPLES._getError(req.responseXML));
               }
           }
       },
       _getError: function (faultXml) {
           ///<summary>
           /// Parses the WCF fault returned in the event of an error.
           ///</summary>
           ///<param name="faultXml" Type="XML">
           /// The responseXML property of the XMLHttpRequest response.
           ///</param>
           var errorMessage = "Unknown Error (Unable to parse the fault)";
           if (typeof faultXml == "object") {
               try {
                   var bodyNode = faultXml.firstChild.firstChild;
                   //Retrieve the fault node
                   for (var i = 0; i < bodyNode.childNodes.length; i++) {
                       var node = bodyNode.childNodes[i];
                       //NOTE: This comparison does not handle the case where the XML namespace changes
                       if ("s:Fault" == node.nodeName) {
                       for (var j = 0; j < node.childNodes.length; j++) {
                           var faultStringNode = node.childNodes[j];
                           if ("faultstring" == faultStringNode.nodeName) {
                               errorMessage = faultStringNode.text;
                               break;
                           }
                       }
                       break;
                   }
               }
           }
           catch (e) { };
        }
        return new Error(errorMessage);
     },
 __namespace: true
};




To understand how to parse the response please review my post on using the DOM parser.
Now you can call the SDK.SAMPLES.BackgroundSendEmailRequest function from your form jscript handler.

Thats all there is to it!
-

Wednesday, February 8, 2012

Send an Email Synchronously in Microsoft Dynamics CRM 2011 using C# or Jscript

This illustration shows how to send an email synchronously in Microsoft Dynamics CRM 2011 with SendEmailRequest.  This example will be given in Jscript (SOAP) and in C# (.NET).

NOTE: Yesterday's post covered creating the email activity in CRM in code (a prerequisite to today's tutorial).  Check it out if you are having trouble creating the entity: http://mileyja.blogspot.com/2012/02/create-email-activity-in-microsoft.html

Ok, here is what the code looks like!
First in C#:
SendEmailRequest ser = new SendEmailRequest();
//Issue send specifies whether to really send the email, or just mark it sent.
ser.IssueSend = true;
//Guid of email activity to send
ser.EmailId = new Guid("dc946d36-3e41-e111-9d05-0050569838b7");
ser.TrackingToken = "";
service.Execute(ser);


If you need help instantiating a service object in .NET within a plugin check out this post:
http://mileyja.blogspot.com/2011/04/instantiating-service-object-within.html

Now here is the Jscript nicely formatted by the CRM 2011 SOAP formatter. Available at: http://crm2011soap.codeplex.com/

Now in Jscript

if (typeof (SDK) == "undefined")
   { SDK = { __namespace: true }; }
       //This will establish a more unique namespace for functions in this library. This will reduce the 
       // potential for functions to be overwritten due to a duplicate name when the library is loaded.
       SDK.SAMPLES = {
           _getServerUrl: function () {
               ///<summary>
               /// Returns the URL for the SOAP endpoint using the context information available in the form
               /// or HTML Web resource.
               ///</summary>
               var ServicePath = "/XRMServices/2011/Organization.svc/web";
               var serverUrl = "";
               if (typeof GetGlobalContext == "function") {
                   var context = GetGlobalContext();
                   serverUrl = context.getServerUrl();
               }
               else {
                   if (typeof Xrm.Page.context == "object") {
                         serverUrl = Xrm.Page.context.getServerUrl();
                   }
                   else
                   { throw new Error("Unable to access the server URL"); }
                   }
                  if (serverUrl.match(/\/$/)) {
                       serverUrl = serverUrl.substring(0, serverUrl.length - 1);
                   } 
                   return serverUrl + ServicePath;
               }, 
           SendEmailRequest: function () {
               var requestMain = ""
               requestMain += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
               requestMain += "  <s:Body>";
               requestMain += "    <Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
               requestMain += "      <request i:type=\"b:SendEmailRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">";
               requestMain += "        <a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>EmailId</c:key>";
               requestMain += "            <c:value i:type=\"d:guid\" xmlns:d=\"http://schemas.microsoft.com/2003/10/Serialization/\">dc946d36-3e41-e111-9d05-0050569838b7</c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>IssueSend</c:key>";
               requestMain += "            <c:value i:type=\"d:boolean\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\">true</c:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <c:key>TrackingToken</c:key>";
               requestMain += "            <c:value i:type=\"d:string\" xmlns:d=\"http://www.w3.org/2001/XMLSchema\" />";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "        </a:Parameters>";
               requestMain += "        <a:RequestId i:nil=\"true\" />";
               requestMain += "        <a:RequestName>SendEmail</a:RequestName>";
               requestMain += "      </request>";
               requestMain += "    </Execute>";
               requestMain += "  </s:Body>";
               requestMain += "</s:Envelope>";
               var req = new XMLHttpRequest();
               req.open("POST", SDK.SAMPLES._getServerUrl(), false)
               req.setRequestHeader("Accept", "application/xml, text/xml, */*");
               req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
               req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
               req.send(requestMain);
               //work with the response here
               //var strResponse = req.responseXML.xml;
               //alert(strResponse.toString());
           },
 __namespace: true
};




To understand how to parse the response please review my post on using the DOM parser.
Now you can call the SDK.SAMPLES.SendEmailRequest function from your form jscript handler.

Thats all there is to it!
-

Tuesday, February 7, 2012

Create an Email Activity in Microsoft Dyanamics CRM 2011 Using C# or Jscript

This illustration shows how to create an email activity in Microsoft Dynamics CRM 2011 with CreateRequest.  This example will be given in Jscript (SOAP) and in C# (.NET).

Ok, here is what the code looks like!
First in C#:

CreateRequest reqCreate = new CreateRequest();
Entity emailCreate = new Entity("email");
emailCreate["subject"] = "test subject";
emailCreate["description"] = " test description";

//specify the owner for the mail (if necessary)
//emailCreate["ownerid"] = new EntityReference("systemuser", new Guid(OwnerId));

Entity ap = new Entity();
Entity ap2 = new Entity();

//You can comment out the line for addressused and use the partid instead to use an entity reference for an activity party
//I just wanted to show how you can specify an email address for an email as an activity party without an entity to go with it.
ap = new Entity("activityparty");
//ap["partyid"] = new EntityReference("systemuser", new Guid("CE08EE7F-4F36-E111-B6F6-0050569838D6"));
ap["addressused"] = "mileyja@gmail.com";
Entity[] aryTo = { ap };
emailCreate["to"] = aryTo;
    
//I am assigning a systemuser entity to the From attribute for the email acitivity 
ap2 = new Entity("activityparty");
ap2["partyid"] = new EntityReference("systemuser", new Guid("CE08EE7F-4F36-E111-B6F6-0050569838D6"));
Entity[] aryFrom = { ap2 };
emailCreate["from"] = aryFrom;

// This is how you assign an a reguarding object
emailCreate["regardingobjectid"] = new EntityReference("account", new Guid("AC946D36-3E41-E111-9D05-0050569838D6"));

reqCreate.Target = emailCreate;
CreateResponse resp = (CreateResponse)slos.Execute(reqCreate);

If you need help instantiating a service object in .NET within a plugin check out this post:
http://mileyja.blogspot.com/2011/04/instantiating-service-object-within.html


Now here is the Jscript nicely formatted by the CRM 2011 SOAP formatter. Available at: http://crm2011soap.codeplex.com/

Now in Jscript


Note:  This request library for jscript is written as CreateEntityRequest, but the underlying call is just a CreateRequest to create an email entity.  Please review the tags of the underlying jscript call's XML for more info.

This example is asynchronous, if you want to learn how to make JScript SOAP calls synchronously please visit this posthttp://mileyja.blogspot.com/2011/07/using-jscript-to-access-soap-web.html


if (typeof (SDK) == "undefined")
   { SDK = { __namespace: true }; }
       //This will establish a more unique namespace for functions in this library. This will reduce the 
       // potential for functions to be overwritten due to a duplicate name when the library is loaded.
       SDK.SAMPLES = {
           _getServerUrl: function () {
               ///<summary>
               /// Returns the URL for the SOAP endpoint using the context information available in the form
               /// or HTML Web resource.
               ///</summary>
               var ServicePath = "/XRMServices/2011/Organization.svc/web";
               var serverUrl = "";
               if (typeof GetGlobalContext == "function") {
                   var context = GetGlobalContext();
                   serverUrl = context.getServerUrl();
               }
               else {
                   if (typeof Xrm.Page.context == "object") {
                         serverUrl = Xrm.Page.context.getServerUrl();
                   }
                   else
                   { throw new Error("Unable to access the server URL"); }
                   }
                  if (serverUrl.match(/\/$/)) {
                       serverUrl = serverUrl.substring(0, serverUrl.length - 1);
                   } 
                   return serverUrl + ServicePath;
               }, 
           CreateEntityRequest: function () {
               var requestMain = ""
               requestMain += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
               requestMain += "  <s:Body>";
               requestMain += "    <Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
               requestMain += "      <request i:type=\"a:CreateRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
               requestMain += "        <a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <b:key>Target</b:key>";
               requestMain += "            <b:value i:type=\"a:Entity\">";
               requestMain += "              <a:Attributes>";
               requestMain += "                <a:KeyValuePairOfstringanyType>";
               requestMain += "                  <b:key>subject</b:key>";
               requestMain += "                  <b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">test subject</b:value>";
               requestMain += "                </a:KeyValuePairOfstringanyType>";
               requestMain += "                <a:KeyValuePairOfstringanyType>";
               requestMain += "                  <b:key>description</b:key>";
               requestMain += "                  <b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\"> test description</b:value>";
               requestMain += "                </a:KeyValuePairOfstringanyType>";
               requestMain += "                <a:KeyValuePairOfstringanyType>";
               requestMain += "                  <b:key>to</b:key>";
               requestMain += "                  <b:value i:type=\"a:ArrayOfEntity\">";
               requestMain += "                    <a:Entity>";
               requestMain += "                      <a:Attributes>";
               requestMain += "                        <a:KeyValuePairOfstringanyType>";
               requestMain += "                          <b:key>addressused</b:key>";
               requestMain += "                          <b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">mileyja@gmail.com</b:value>";
               requestMain += "                        </a:KeyValuePairOfstringanyType>";
               requestMain += "                      </a:Attributes>";
               requestMain += "                      <a:EntityState i:nil=\"true\" />";
               requestMain += "                      <a:FormattedValues />";
               requestMain += "                      <a:Id>00000000-0000-0000-0000-000000000000</a:Id>";
               requestMain += "                      <a:LogicalName>activityparty</a:LogicalName>";
               requestMain += "                      <a:RelatedEntities />";
               requestMain += "                    </a:Entity>";
               requestMain += "                  </b:value>";
               requestMain += "                </a:KeyValuePairOfstringanyType>";
               requestMain += "                <a:KeyValuePairOfstringanyType>";
               requestMain += "                  <b:key>from</b:key>";
               requestMain += "                  <b:value i:type=\"a:ArrayOfEntity\">";
               requestMain += "                    <a:Entity>";
               requestMain += "                      <a:Attributes>";
               requestMain += "                        <a:KeyValuePairOfstringanyType>";
               requestMain += "                          <b:key>partyid</b:key>";
               requestMain += "                          <b:value i:type=\"a:EntityReference\">";
               requestMain += "                            <a:Id>ce08ee7f-4f36-e111-b6f6-0050569838d6</a:Id>";
               requestMain += "                            <a:LogicalName>systemuser</a:LogicalName>";
               requestMain += "                            <a:Name i:nil=\"true\" />";
               requestMain += "                          </b:value>";
               requestMain += "                        </a:KeyValuePairOfstringanyType>";
               requestMain += "                      </a:Attributes>";
               requestMain += "                      <a:EntityState i:nil=\"true\" />";
               requestMain += "                      <a:FormattedValues />";
               requestMain += "                      <a:Id>00000000-0000-0000-0000-000000000000</a:Id>";
               requestMain += "                      <a:LogicalName>activityparty</a:LogicalName>";
               requestMain += "                      <a:RelatedEntities />";
               requestMain += "                    </a:Entity>";
               requestMain += "                  </b:value>";
               requestMain += "                </a:KeyValuePairOfstringanyType>";
               requestMain += "                <a:KeyValuePairOfstringanyType>";
               requestMain += "                  <b:key>regardingobjectid</b:key>";
               requestMain += "                  <b:value i:type=\"a:EntityReference\">";
               requestMain += "                    <a:Id>ac946d36-3e41-e111-9d05-0050569838d6</a:Id>";
               requestMain += "                    <a:LogicalName>account</a:LogicalName>";
               requestMain += "                    <a:Name i:nil=\"true\" />";
               requestMain += "                  </b:value>";
               requestMain += "                </a:KeyValuePairOfstringanyType>";
               requestMain += "              </a:Attributes>";
               requestMain += "              <a:EntityState i:nil=\"true\" />";
               requestMain += "              <a:FormattedValues />";
               requestMain += "              <a:Id>00000000-0000-0000-0000-000000000000</a:Id>";
               requestMain += "              <a:LogicalName>email</a:LogicalName>";
               requestMain += "              <a:RelatedEntities />";
               requestMain += "            </b:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "        </a:Parameters>";
               requestMain += "        <a:RequestId i:nil=\"true\" />";
               requestMain += "        <a:RequestName>Create</a:RequestName>";
               requestMain += "      </request>";
               requestMain += "    </Execute>";
               requestMain += "  </s:Body>";
               requestMain += "</s:Envelope>";
               var req = new XMLHttpRequest();
               req.open("POST", SDK.SAMPLES._getServerUrl(), true)
               req.setRequestHeader("Accept", "application/xml, text/xml, */*");
               req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
               req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
               var successCallback = null;
               var errorCallback = null;
               req.onreadystatechange = function () { SDK.SAMPLES.CreateEntityResponse(req, successCallback, errorCallback); };
               req.send(requestMain);
           },
       CreateEntityResponse: function (req, successCallback, errorCallback) {
               ///<summary>
               /// Recieves the assign response
               ///</summary>
               ///<param name="req" Type="XMLHttpRequest">
               /// The XMLHttpRequest response
               ///</param>
               ///<param name="successCallback" Type="Function">
               /// The function to perform when an successfult response is returned.
               /// For this message no data is returned so a success callback is not really necessary.
               ///</param>
               ///<param name="errorCallback" Type="Function">
               /// The function to perform when an error is returned.
               /// This function accepts a JScript error returned by the _getError function
               ///</param>
               if (req.readyState == 4) {
               if (req.status == 200) {
               if (successCallback != null)
               { successCallback(); }
               }
               else {
                   errorCallback(SDK.SAMPLES._getError(req.responseXML));
               }
           }
       },
       _getError: function (faultXml) {
           ///<summary>
           /// Parses the WCF fault returned in the event of an error.
           ///</summary>
           ///<param name="faultXml" Type="XML">
           /// The responseXML property of the XMLHttpRequest response.
           ///</param>
           var errorMessage = "Unknown Error (Unable to parse the fault)";
           if (typeof faultXml == "object") {
               try {
                   var bodyNode = faultXml.firstChild.firstChild;
                   //Retrieve the fault node
                   for (var i = 0; i < bodyNode.childNodes.length; i++) {
                       var node = bodyNode.childNodes[i];
                       //NOTE: This comparison does not handle the case where the XML namespace changes
                       if ("s:Fault" == node.nodeName) {
                       for (var j = 0; j < node.childNodes.length; j++) {
                           var faultStringNode = node.childNodes[j];
                           if ("faultstring" == faultStringNode.nodeName) {
                               errorMessage = faultStringNode.text;
                               break;
                           }
                       }
                       break;
                   }
               }
           }
           catch (e) { };
        }
        return new Error(errorMessage);
     },
 __namespace: true
};




To understand how to parse the response please review my post on using the DOM parser.
Now you can call the SDK.SAMPLES.CreateEntityRequest function from your form jscript handler.

Thats all there is to it!
-

Monday, February 6, 2012

Check Out What's Coming in the 2012 Q2 Service Release of Microsoft Dynamics CRM 2011

Microsoft just released the release preview guide for the scheduled Q2 2012 service update and you can download a copy here:

http://crmpublish.blob.core.windows.net/docs/ReleasePreviewGuide.pdf

It details some great new features that are coming to the platform, here are my three favorites:

CRM Anywhere (Cross-Browser Support): One of the biggest headaches CRM users bring forward is that they have trouble getting it to work on Mac or that it's not supported in anything other than Internet Explorer.  This release will see all that go away and open up CRM to the masses in a new way.

Official SQL Server 2012 Support:  I have personally seen CRM already work on the SQL 2012 RC0 and it seems to work well right now with the exception of it connection to reporting services.  Official support for SQL 2012 will be part of this release.

New CRM Mobile Client: It looks like Microsoft is getting off their butts on allowing ISV's to fill this gap in their product by releasing a new mobile client  for Windows Phone 7, Android IOS, and Blackberry that will allow better access to your CRM data on those platforms and will even allow offline mode for access to data when you don't have connectivity.

There are some other features being released like social feed enhancements and such, but above are my top three.

Have great day and check out the release guide!

-