Monday, February 27, 2012

Delete an Entity Record in Microsoft Dynamics CRM 2011 Using Silverlight

This tutorial will show you how to delete an entity record in Microsoft Dynamics CRM 2011 using C# in Silverlight.

First things first.  You have to set up your Silverlight app to make a web services connection to CRM.   The best tutorial I have found for this is located here in the MSDN:
http://msdn.microsoft.com/en-us/library/gg594452.aspx

Here is the call in C#:

//delete request
OrganizationRequest request = new OrganizationRequest() { RequestName = "Delete" };
EntityReference entrefDeleteTarget = new EntityReference();
entrefDeleteTarget.Id = new Guid("A42D83C5-5E61-E111-AC43-1CC1DEF1B5FF");
entrefDeleteTarget.LogicalName = "account";
request["Target"] = entrefDeleteTarget;


IOrganizationService service = SilverlightUtility.GetSoapService();

service.BeginExecute(request, new AsyncCallback(AccountDelete_ClickCallback), service);

You will notice that the biggest change in thinking and syntax will be that you have to specify your request and response properties as strings explicitly in code.

- I hope this helps!!

Wednesday, February 22, 2012

Help Microsoft Dynamics CRM be Number 1 on LinkedIn!

There is a fun poll on LinkedIn that is going around and let's you speculate who will be number 1 in five years out of the top 5 CRM systems.

You can find it here:
http://linkd.in/w24SJ5


- Happy Wednesday!

Tuesday, February 21, 2012

How to Use DeleteRequest to Delete an Entity in Microsoft Dynamics CRM 2011 with VB.NET

This illustration shows how to use DeleteRequest to delete an entity in Microsoft Dynamics CRM 2011 with VB.NET

Ok, here is what the code looks like!

In VB.NET

Dim req As New DeleteRequest()
req.Target = New EntityReference("account", New Guid("72876387-9E5C-E111-B314-1CC1DEF1353B"))
Dim resp As DeleteResponse = DirectCast(service.Execute(req), DeleteResponse)


Thats all there is to it!
-

Monday, February 20, 2012

Update Rollup 6 Causing Some Access Denied Issues - IgnoreTokenCheck Ramifications?

I have been seeing an uptick of complaints in the forums regarding Update Rollup 6 causing "Access Denied" issues.

Example with workaround: http://social.microsoft.com/Forums/en/crmdevelopment/thread/57032ef6-c690-4ab2-a7e1-21f1081e5350?prof=required

It seems you can add a IgnoreTokenCheck registry to fix the issue as a workaround.

HKLM>Software>Microsoft>MSCRM>IgnoreTokenCheck (Dword)=1


I am wondering what the risks and ramifications might be of this operation and maybe the community at large could help out by discussing them at this linked forum if they know anything.

 - Thanks!

Saturday, February 18, 2012

A Way to a Better Career, Even if You Know Nothing About Development!

I just want to let everyone know how lucky I am that I chose Microsoft .NET software development as my chosen career path.  I have seen my salary more than triple since I got into this business back in 2005 and it's been a great ride.  I can say that most major cities have a decent amount of work available if they aren't chomping at the bit for these people already.

I have been fortunate enough to have found an additional niche area that has made me even more valuable.  You can do this by finding a high demand area that requires your skills and honing your skill proficiency to suit that market.  My chosen market is Microsoft Dynamics CRM but it could doing .NET development as it applies to SharePoint or any other high demand field that utilizes .NET development.

Even, if you know nothing there is hope.  I could hire five .NET people today and many more when we sell our next gig but we can't honestly find enough good people.    Download Visual Studio Express and go through the tutorial videos linked below.


My recommendation would be to start from scratch (the videos above) and then work your way into a .NET certification program.  The tests are $150 a piece.  As an example, in the Twin Cities you can expect to earn close to 40-50k as an entry level .NET developer.  Honestly, within five years you should be able to work your way into 90k.  Even more exciting is the fact that they have clamped down on H1-B visas which has boosted the price.  In the Washington DC area there is plenty of jobs (for qualified individuals) to make over 140k in .NET dev for CRM.  I have seen the values for these people go up rapidly in recent years and that trend  does not seem to be slowing at all.

-I hope this helps!

Thursday, February 16, 2012

PHP - Easy Install on IIS

I found a great easy installer on the Microsoft site to easily install PHP on IIS.  I figure someone else besides me might find this handy.

Check it out:
http://www.microsoft.com/web/platform/phponwindows.aspx

-

Wednesday, February 15, 2012

Slow xRM's Video Collection and 66x48 Icons in CRM 2011

Today is a little different and I will just highlight a couple quick things.

Slow xRM has a great collection of over 100 instructional videos for CRM 2011 over on his site here:
http://slowxrm.blogspot.com/2012/01/more-than-100-videos-dedicated-to.html

Also, on a funny note, I found out the other day that the 66x48 icons (what a weird size anyways) that you can enter in CRM 2011 for an entity aren't actually used for anything.  Thanks to Jim Daly at MSFT for pointing me to this article and clearing that up.  I spent gosh knows how much time over the last year or so stretching my normal icons to make that goofy size.  I guess it was all for nothing.


- Have a good Wednesday!

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!

-