Thursday, January 17, 2013

Using early binding (typed WCF classes) in CRM 2011

Introduction

Strongly typed entities are NOT part of the WSDL - which means that custom entities are not discoverable using WSDL.

The parent type is Entity, and then the instances, i.e. Account, are based on Entity. This means that the any proxies you register are uniform across all organisations. The Entity class has a generic list of attributes, which can contain all the fields and other properties of the original CRM entity. Therefore, you do not have to have a strongly typed "local" class in your client to access the data. An example of this can be seen at this blog: Use WCF to get CRM version and user name.

These are some useful properties and methods of the Entity class:


// You can identify specific named columns using this collection
public AttributeCollection Attributes

//You can get the special metadataformatting originally. For example,
// string s=   account.FormattedValues["creditlimit"] 
// s now = 1,500,000.00 instead of 1500000
public FormattedValueCollection FormattedValues

//The unique identifier for the Entity
public virtual Guid Id

//The friendly name for the Entity, i.e. Account
public string LogicalName

//Names of related entities;
public RelatedEntityCollection RelatedEntities

//Simplifies casting when assigning values
protected virtual void SetAttributeValue(string attributeLogicalName, object value);

//Simplifies casting a retrieved Entity object to a specific CRM Entity
public T ToEntity<T>() where T : Entity;

So if this is the only content of the retrieved WSDL, how do you strongly type retrieved entities? Regular WCF provides the ability to create local proxy classes, by virtue of WSDL containing all the entity classes.

The Code Generator

Source Code Generator Tool generates these entity classes for you. It bases the generation of the code based on the CRM Metadata. It is included in the SDK. Once you have generated these classes, it would be useful to create a separate library for them and reference them across multiple projects for example.

To make use of this library you pass in the assembly when defining the behavior. For example, instead of this:

//INITIALIZE PIPELINE SERVICE
serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());

You would do this:
serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior(MyGeneratedClassLibrary));

Somewhat similar to WCF Odata services, where you pass in the name of the Entity Data Model to the service.

Running the crmsvcutil.exe tool

Note: More information is available on MSDN at Code Generation Using the CrmSvcUtil Tool

You will also need to install Windows Identity Foundation from http://www.microsoft.com/en-us/download/details.aspx?id=17331


On my PC the tool is located at C:\CRM\sdk\bin\crmsvcutil.exe.
Open a command line in this folder and run the following:

CrmSvcUtil.exe /url:http://crmdevmt.develop.fcbt:5555/JamesDev/XRMServices/2011/Organization.svc /out:GeneratedCode.cs /namespace:fcbt.crm.baseline /serviceContextName:CrmDataContext
Where:
  • http://crmdevmt.develop.fcbt:5555 is the Server and Port of the CRM server
  • JamesDev is the name of the organization, and
  • XRMServices/2011/Organization.svc should stay the same for everything.
  • GeneratedCode.cs is the name of the file generated.
  • fcbt.crm.baseline is the name of the namespace I want to use for the generated code
  • CrmDataContext is the name of the service context for Linq. Its optional.

Using the Generated File

Its huge. Yes, a common experience for some. I recommend unloading Devexpress before you open the file in Visual Studio.

Copy the generated file and include it in your Visual Studio project.

Taken from MSDN:
In order to work with the classes you also need to add references to the following Microsoft Dynamics CRM and .NET assemblies:
Add references to these assembliesAssembly location
Microsoft.Crm.Sdk.dll
Microsoft.Crm.SdkTypeProxy.dll
For on-premises or IFD, browse to the SDK\Bin (32-bit) or SDK\Bin\64-bit folder.
For online, browse to the SDK\Bin\Online\64-bit folder. These assemblies work in both 32-bit and 64-bit environments.
Microsoft.Xrm.Client
Microsoft.Xrm.Portal
Microsoft.Xrm.Portal.Files
From the SDK\Microsoft.Xrm\Bin folder.
System.Data.Services
System.Data.Services.Client
From the .NET tab.

  1. Create a windows form and add the following Usings:

    using System;
    using System.ServiceModel.Description;
    using System.Windows.Forms;
    using Microsoft.Crm.Sdk.Messages;
    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Client;
    using Microsoft.Xrm.Sdk.Query;
     
  2. Add the following labels and textboxes to the form:
    • Server URL: textBoxServerUrl
    • Org: textBoxOrg
    • Domain: textBoxDomain
    • UserName: textBoxName
    • Password: textBoxPassword
  3. Add another label and textbox, with an Add button:
    • Account name: textboxAccountName
    • buttonAdd: Add account
  4. You should have something that looks like this: 
  5. Embed this code in the click event of the AddNewRecord button:
    //SET UP CREDENTIALS
    Uri OrganizationUri = new Uri(textBoxServerUrl.Text + "/" + textBoxOrg.Text + "/XRMServices/2011/Organization.svc");
    ClientCredentials Credentials = new ClientCredentials();
    Credentials.Windows.ClientCredential = new System.Net.NetworkCredential(textBoxName.Text, textBoxPassword.Text, textBoxDomain.Text);

    //INITIALIZE PIPELINE SERVICE
    OrganizationServiceProxy serviceProxy = new OrganizationServiceProxy(OrganizationUri, null, Credentials, null);
    serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
    IOrganizationService service = (IOrganizationService)serviceProxy;

    fcbt.crm.baseline.Account a = new fcbt.crm.baseline.Account();
    a.Name = textBoxAccountName.Text;
    a.Telephone1 = "123";
    Guid g = service.Create(a); 



  6.  Run the code, and fill in a value in the account name, then click the Add new record button. Go to CRM and refresh the account list, there will be your new account.



No comments:

Post a Comment