Retrieving Entity Data Using JScript

This is a step-by-step recipe for retrieving CRM entity data using JScript and the OData (REST) endpoint in an asynchronous manner.

1. Install JScript Editor Extensions  in Visual Studio.

2. Install Visual Studio project template by double-clicking SDK\Templates\XrmPageScriptDevelopmentProjectCS.vsix.

3. Import SDK\Templates\Xrm.PageScriptProjectTemplate\XrmPageScriptDevelopmentFormSnapshot_1_0_0_0_managed.zip in CRM.

4. Create a new project and select the Xrm.Page JScript Library Project template.

5. Open an instance of the form, in my case the Quote Product form, and click Xrm.Page on the Customize tab.

6. Click Get Data and then Copy to Clipboard.

7. In your Visual Studio project, replace the contents of PageData.js with the contents of your clipboard.

8. Add a new JScript file called e.g. Product.js with following contents:

/// <reference path=”XrmPageTemplate.js” />
/// <reference path=”SDK.JScriptRESTDataOperations.js” />
function retrieveProduct() {
// This assumes there is a lookup field called productid that contains the selected product.
var lookup = Xrm.Page.getAttribute(“productid”).getValue();
var id = lookup[0].id;
SDK.JScriptRESTDataOperations.Retrieve(
id,
“Product”,
function (product) {
alert(“Retrieved the product named \”” + product.Name + “\”. This product was created on : \”” + product.CreatedOn + “\”.”);
},
errorHandler
);
}

function errorHandler(error)  {
alert(error.message);
}

9. In your CRM solution, add the following web resources:

10. Add these web resources as libraries on the form.

11. Add a call to retrieveProduct e.g. on the productid OnChange event.

Advertisements

Microsoft Dynamics CRM 2011 Online Integration Getting Started (Early Bound)

This is a follow up to my previous post Microsoft Dynamics CRM 2011 Online Integration Getting Started (Late Bound). Here I list the steps that I had to do different to work with early binding.

After creating the project, I ran CrmSvcUtil.exe:

<location of sdk>\bin\CrmSvcUtil.exe /url:https://xxx.api.crm4.dynamics.com/XRMServices/2011/Organization.svc /out:”C:\Users\henols02\Documents\Visual Studio 2010\Projects\<project name>\Models\CrmModel.cs” /namespace:<project name>.Models /serviceContextName:CrmServiceContext /username:”<Windows Live ID” /password:”<password>”

and added the resulting CrmModel.cs to the project in the Models folder.

After creating the service proxy (in LogOn method), early bound support had to be added using the following statement:

serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new Microsoft.Xrm.Sdk.Client.ProxyTypesBehavior());

In the created controller, getting the context and retrieving the data is done in a slightly different (simpler) way:

var context = new Elevregister1.Models.CrmServiceContext(service);
var elever = context.elev_elevSet.ToList();

I created the view as a strongly-type view:

image

Then, I removed the unwanted columns.

Microsoft Dynamics CRM 2011 Online Integration Getting Started (Late Bound)

This is a log of what I did to create a very simple ASP.NET MVC application that retrieves data from Microsoft Dynamics CRM 2011 Online. I had a custom entity called Elev.

1. Created an ASP.NET MVC 3 Web Application with template Internet Application.

2. Added references to

  • microsoft.crm.sdk.proxy
  • microsoft.xrm.sdk
  • System.ServiceModel
  • System.Runtime.Serialization
  • System.Security.

3. Created a new folder called Helpers and add <location of sdk>\samplecode\cs\helpercode\deviceidmanager.cs to it.

4. Modified AccountController LogOn to create a CRM service proxy and store it in the user’s session:

[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
//if (Membership.ValidateUser(model.UserName, model.Password))
try
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);

// Added for CRM
var clientCredentials = new System.ServiceModel.Description.ClientCredentials();
clientCredentials.UserName.UserName = model.UserName;
clientCredentials.UserName.Password = model.Password;
var serviceProxy = new Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy(
new Uri(“https://xxx.api.crm4.dynamics.com/XRMServices/2011/Organization.svc&#8221;),
null,
clientCredentials,
Microsoft.Crm.Services.Utility.DeviceIdManager.LoadOrRegisterDevice());
Session.Add(“ServiceProxy”, serviceProxy);
// End added for CRM

if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith(“/”)
&& !returnUrl.StartsWith(“//”) && !returnUrl.StartsWith(“/\\”))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction(“Index”, “Home”);
}
}
//else
catch (Exception ex)
{
//ModelState.AddModelError(“”, “The user name or password provided is incorrect.”);
ModelState.AddModelError(“”, ex);
}
}

// If we got this far, something failed, redisplay form
return View(model);
}

5. Modified AccountController LogOff as follows:

public ActionResult LogOff()
{
var serviceProxy = Session[“ServiceProxy”] as Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy;
if (serviceProxy != null)
{
Session.Remove(“ServiceProxy”);
serviceProxy.Dispose();
}

FormsAuthentication.SignOut();

return RedirectToAction(“Index”, “Home”);
}

6. Created a new controller with empty read/write actions called ElevController.

image

7. Added the following code:

public ActionResult Index()
{
var service = Session[“ServiceProxy”] as Microsoft.Xrm.Sdk.IOrganizationService;
if (service != null)
{
var context = new Microsoft.Xrm.Sdk.Client.OrganizationServiceContext(service);
var query = from e in context.CreateQuery(“elev_elev”) select e;
var elever = query.ToList();
return View(elever);
}
else
{
ModelState.AddModelError(“”, “ServiceProxy missing in session state. Did you log in?”);
return RedirectToAction(“LogOn”, “Account”);
}
}

8. Added a new folder in Views called Elev.

9. Added a new view called Index:

image

10. Added the following code:

@model IEnumerable<Microsoft.Xrm.Sdk.Entity>

@{
ViewBag.Title = “Index”;
}

<h2>Index</h2>

<p>
@Html.ActionLink(“Ny”, “Create”)
</p>
<table>
<tr>
<th>
Namn
</th>
<th>
Personnummer
</th>
</tr>

@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item[“elev_name”])
</td>
<td>
@Html.DisplayFor(modelItem => item[“elev_personnummer”])
</td>
<td>
@Html.ActionLink(“Redigera”, “Edit”, new { id=item.Id }) |
@Html.ActionLink(“Detaljer”, “Details”, new { id = item.Id }) |
@Html.ActionLink(“Ta bort”, “Delete”, new { id = item.Id })
</td>
</tr>
}

</table>

11. Added a link on the Home/Index page:

<p>@Html.ActionLink(“Elever”, “Index”, “Elev”)</p>

Adding a Dashboard to a Custom Area (Pane)

Changing navigation is still a matter of hand editing customizations.xml in your favorite XML editor. I wanted to have a new area (pane) with my custom entities and a map (implemented as a dashboard). I accomplished this by inserting the following inside the <SiteMap> element:

      <Area Id="G7" ResourceId="Area_G7" ShowGroups="true" Icon="/_imgs/services_24x24.gif" Title="Custom Area">
         <Group Id="G7" Title="Custom Group">
           <SubArea Id="st_map" Icon="/_imgs/area/18_home.gif" Title="Map" Url="/workplace/home_dashboards.aspx?dashboardId=%7b67f12cbc-a386-e011-8da7-18a9056eb611%7d">
             <Titles>
               <Title LCID="1033" Title="Map"/>
               <Title LCID="1053" Title="Karta"/>
             </Titles>
           </SubArea>
           <SubArea Id="customEntityId1" Entity="Custom Entity 1" />
           <SubArea Id="customEntityId2" Entity="Custom Entity 2" />
         </Group>
       </Area>

The important thing is the URL, in this case /workplace/home_dashboards.aspx?dashboardId=%7b67f12cbc-a386-e011-8da7-18a9056eb611%7d. I got this URL by going to WorkPlace –> Dashboards and clicking on the right arrow and then right-clicking on my Map dashboard.

image

Integrating CRM 2011 (on-line) with Windows Azure AppFabric

I just did the same as in my previous post but with the on-line version of CRM. You can then skip all the CRM configuration steps.

The discovery URL to use in the plug-in registration tool is https://dev.crm4.dynamics.com (for Europe).

The issuer name is on the Settings->Customization->Developer Resources page: crm4.dynamics.com (once again for Europe).

Integrating CRM 2011 (on-premise) with Windows Azure AppFabric

One of the new features of CRM 2011 is out-of-the-box integration with the Windows Azure service bus (Windows Azure AppFabric). I tried to test this feature with CTP4 but did not reach a working solution. With the beta, it was relatively easy. The documentation is fairly complete, but some steps are not described in detail. Here is a walk-through.

Configure CRM for Integration with Windows Azure

Obtain a certificate

Create a self-signed certificate and put it in the personal store in local computer:

makecert -n "CN=CRMAzure" -sr LocalMachine -ss My –r

Copy the certificate from Personal to Trusted Root Certification Authorities.

image

Export the public key in Base64 format to e.g. CRMAzure.cer.

Configure Certificate Read Access

Add permission for your CRM service account, in my case Network Service, to access the private key by right-clicking on the certificate and choosing All Tasks -> Manage Private Keys…

image

Configure the CRM Database (MSCRM_Config)

Register the CRM PowerShell cmdlets

On a PowerShell command line, type

Add-PSSnapin Microsoft.Crm.PowerShell

If you get the following error message:

Add-PSSnapin : The Windows PowerShell snap-in ‘Microsoft.Crm.PowerShell’ is not installed on this machine.

You must first install this snap-in by running

C:WindowsMicrosoft.NETFramework64v4.0.30319InstallUtil.exe "C:Program FilesMicrosoft Dynamics CRMToolsMicrosoft.Crm.PowerShell.dll"

When doing that, you might get the following error:

Add-PSSnapin : Cannot load Windows PowerShell snap-in Microsoft.Crm.PowerShell because of the following error: Could not load file or assembly ‘file:///C:Program FilesMicrosoft Dynamics CRMToolsMicrosoft.Crm.PowerShell.dll’ or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.

You can fix this by instructing Windows to always use the 4.0 CLR with the following command:

reg add hklmsoftwarewow6432nodemicrosoft.netframework /v OnlyUseLatestCLR /t REG_DWORD /d 1

Set the CRM certificate

On the PowerShell command line, type the following command:

set-crmcertificate -CertificateType AppFabricIssuer -Name <issuerName> -StoreName My -StoreLocation LocalMachine -StoreFindType FindBySubjectDistinguishedName -DataFile <certificateFilename>

In my case:

set-crmcertificate -CertificateType AppFabricIssuer -Name CRMAzure -StoreName My -StoreLocation LocalMachine -StoreFindType FindBySubjectDistinguishedName -DataFile C:UsersAdministratorDocumentsCRMAzure.cer

Register an Azure-aware Plug-in using the Plug-in Registration Tool

Connect to the Microsoft Dynamics CRM Server

Use http://<host&gt;:5555 as discovery URL.

image

Create a Service Endpoint Configuration

image

The solution namespace should match your AppFabric service namespace, which you can look up at appfabric.azure.com.

image

The path should match the path you’re going to use in your listener.

Press Save & Configre ACS.

Configure AppFabric ACS

Here is good news in the beta. Rather than running ACM commands, you can let the plug-in registration tool do the necessary Azure AppFabric security configuration for you.

image

You see your management key at the same web page as your namespace.

Register the ServiceBusPlugin Plug-in for an Event

Now you can go ahead and register the out-of-the-box plug-in for an event. Here I register it for creation of contacts.

image

Create and Compile your Service

Using Visual Studio, create a new Windows console C# project. Copy the sample one-way listener code from the SDK documentation (Advanced Development for Microsoft Dynamics CRM -> Azure Extensions for Microsoft Dynamics CRM ->Sample Code for CRM-AppFabric Integration). Compile and run.

Now you can create a contact and if everything works stuff should be printed on the console after a minute or two.