Monthly Archives: August 2011

How to get count of entities in Microsoft CRM 2011

Working on a task, I wanted to know exact number of records for particular entity in CRM 2011 but I wasn’t able to access this information via some standard way and LINQ query with .Count was throwing exception that this type of query is no implemented – The method ‘Count’ is not supported. (I’m talking about class that is generated by crmsvcutil.exe tool from CRM 2011 SDK).

How to solve this… hmmm.

So, there are several posibilites :

When accessing entity with small number of records, you can use this approach :

https://community.dynamics.com/product/crm/crmnontechnical/b/crmsoftwareblog/archive/2011/05/20/fetchxml-2011-total-record-count.aspx

but there is small caveat, default paging in CRM 2011 is set to 5000 records (at least on system that I have my hands on). So returned XML will claim that there is 5000 records, but you have to watch for EntityCollection.MoreRecords bool that is set when this is just page of entities also with PagingCookie that has the value of last record (XML fragment) that CRM knows where to continue (essentialy there is GUID with last record).

Or you can use my snippet :

I created small chunk of code that can retrieve total number of your desired entity and return this as int.

Introducing > the code 🙂 :

/// <summary>
/// Gets the supplied entity count from CRM 2011.
/// </summary>
/// <param name="Service">The CRM 2010 service.</param>
/// <param name="EntityName">Name of the entity we need get count of.</param>
/// <param name="ServicePageSize">Size of the page (optional).</param>
/// <returns></returns>
private int GetEntityCount(IOrganizationService Service, string EntityName, int ServicePageSize = 5000)
{
	RetrieveMultipleResponse retrieved;
	int PageNumber = 1;
	string PagingCookie = string.Empty;
	int PageSize = ServicePageSize;

	do {
		QueryExpression query = new QueryExpression() {
			EntityName = EntityName,
			//ColumnSet = new ColumnSet(Columns),
			PageInfo = new PagingInfo() {
				PageNumber = 1,
				Count = PageSize
			}
		};

		if (PageNumber != 1) {
			query.PageInfo.PageNumber = PageNumber;
			query.PageInfo.PagingCookie = PagingCookie;
		}

		RetrieveMultipleRequest retrieve = new RetrieveMultipleRequest();
		retrieve.Query = query;
		retrieved = (RetrieveMultipleResponse)Service.Execute(retrieve);

		if (retrieved.EntityCollection.MoreRecords) {
			PageNumber++;
			PagingCookie = retrieved.EntityCollection.PagingCookie;
		}
	} while (retrieved.EntityCollection.MoreRecords);

	return ((PageNumber - 1) * PageSize) + retrieved.EntityCollection.Entities.Count;
}

IOrganizationService is class that is in Microsoft.Xrm.Sdk namespace and is used to connect to CRM. I’m using late binding here, so I created via tool (crmsvcutil.exe mentioned earlier) one class per every entity and thus I can call the method like this :

int acc = GetEntityCount(_serviceProxy, Account.EntityLogicalName);

Alternatively you could use string for the second parameter like this :

int acc = GetEntityCount(_serviceProxy, "account");

_serviceProxy is instance properly initialized with credentials and URL to running CRM 2011.

RetrieveMultipleRequest is class located in Microsoft.Crm.Sdk.Messages.

Optionally you could add filtering to the QueryExpression to apply some logic. There are several examples on other blogs.

The traffic from CRM 2011 server is as small as possible, because as you can see (I have commented out ColumnSet collection) there are no columns specified so only column that will be sent is ID (of type GUID).

If you have any additional questions or perhaps there is some easyer way, pls mail me or write them down in the comments.

CRMHelpers.zip – complete class, just include it in your project with referenced assemblies and you are good to go. Feel free to modify.

Hope this helps, enjoy 🙂

How to correctly change and set property of type Money in Microsoft CRM 2011

Yesterday I found out that setting property of type Money on entity can make really difference.

I’m altering Account records via WCF service one at a time and saving the changes in CRM 2011. I was changing some money property like this :

entity.SomeMoneyProperty = new Money() { Value = decimalValue };

Everything compiled and worked fine until I realized, that the value I was setting really isn’t stored in the CRM. But there was no runtime error, nothing.

So I searched the CRM 2011 SDK and found out, that they use only this type of creating the Money property :

entity.SomeMoneyProperty = new Money(decimalValue);

And with this aproach, everything worked fine 🙂 THX SDK, I

Microsoft Silverlight RIA Services app splash screen problem – request to WCF service appears to be cached on Internet Explorer 9 and timeouted

The problem :

Our Silverlight RIA Services application isn’t working under “special” circumstances. These special circumstances are : if user launches another instance of Internet Explorer 9 and tries to load page with Silverlight component, app isn’t loaded and after some time IE displaying just white screen (about 1 minute. BTW you could right click on the white surface and see that there si Silverlight loaded) suddenly displays error about RIA service call timeout.

This is the behaviour when deployed to Windows 2008 R2 with IIS 7.5. When launched from development webserver or local IIS 7.5 on my Windows 7 dev box, things worked fine.

First thoughts :

As first thing, I always launch Fiddler as my tool of choice, when it comes to debugging HTTP traffic. What I saw was normal traffic when IE was instantiated once on my localhost.

Under normal traffic you should understand :

  1. Request to root of the app and IIS returned 401 (please authenticate – see HTTP status codes for reference) (you need to have only windows authentication turned on when using RIA Services),
  2. Browser repeates the request and but this time with authorization cookie and IIS responded with html, that causes browser to download xap and other files,
  3. Downloading Silverlight.js file (cached sometimes),
  4. Downloading our custom SplashScreen.xaml file that is loaded before the whole xap and serves as the name reveales as splash screen of the app,
  5. Downloading .xap file (the whole app, big zipped file),
  6. Downloading some resources (images and so on),
  7. First request to WCF service created by RIA Services and these requests continue as user clicks in the apps and loades requests data (BlablaMainService.svc path requests)

On my machine, traffic looked like this :

ria services traffic

Then I browsed to our test server and traffic looked like this :

ria services problem

(please don’t look at the localhost string, I simulated the problem on my machine after we fixed it)

Let me stop here for a moment. At first, I thought that the browser is caching the service requests somehow. They obviously never left the browser. While looking at the Fiddler I realised that there is also other problem.

The difference is obvious – we are missing the SplashScreen.xaml file and we have some additional requests. Browser requested some .png file, to be specific, this is the image you see when there is no Silverlight installed on your machine, but this is not our case. My colleague had javascript errors in IE9 turned off, so he unfortunatelly didn’t saw this message :

error loading silverlight splashscreen

The solution :

So my first assumption that requests are cached because they never hit the server was wrong. For the first time when the app was fired, IE ignored the SplashScreen.xaml file was missing. Silverlight just displayed normal loading screen and user could continue. Of course, JS error telling that specified .xaml file is missing was there, but you could overlook it. The reason of different behaviour on my Windows 7 dev box and on production Windows 2008 R2 was that the SplashScreen.xaml file’s Build Action in VS 2010 was set to Page and not to Content and thus was not copied to destination dir when deployed. But my local IIS was working on my local copy where this file was present. As always, look at the traffic underneath shiny browser experience, it really matters.

How to read, create, update and detele objects in Microsoft CRM 2011 on premise via WCF service.

Please note that this code works for ON PREMISE installation of Microsoft CRM 2011.

In this short article I will show you how to access items in CRM 2011 via new built in WCF webservice. You should use WCF when accessing CRM from code and REST when accessing from client browser of Silverlight application.

Of course you can use old style CRM 4.0 like aproach with QueryExpression class and then RetreiveMultiple on IOrganizationService instance, but there is also easier approach.

You will need to download and extract CRM 2011 SDK. Current version is 5.0.3 and you can find it on this link : http://www.microsoft.com/downloads/en/details.aspx?FamilyID=420f0f05-c226-4194-b7e1-f23ceaa83b69

Here are the steps you need to follow :

  1. Create console application (with full .NET fw 4.0, not client profile) (you can ofcourse create WPF, WinForms or ASP.NET app, but for our example we will use console app)
  2. Locate crmsvcutil.exe in sdk\bin folder along with microsoft.crm.sdk.proxy.dll and microsoft.xrm.sdk.dll.
  3. Both assemblies add as reference to the console project and add also .NET FWs System.ServiceModel and System.Runtime.Serialization.
  4. Use crmsvcutil.exe to use early bound aproach, that will generate classes for all entities within CRM 2011 and also your custom ones. (this is essential something like adding webservice reference to webservice in CRM 4.0 times). I used commandline arguments like this :crmsvcutil /url:http://server/organization-name/XRMServices/2011/Organization.svc /o:filename.cs /n:namespace /serviceContextName:context-name. /url – url of services, /o – output file, /n – namespace of generated classes, /serviceContextName is name of service, but when you ommit this switch, no context will be generated at all. Context is used for accessing the entities via WCF.
  5. Add generated .cs file to the project (copy to folder, button Show all files, include in project).
  6. Every generated entity will get it’s dedicated IQueryable collection, so for Account you should query AccountSet, for Annotation you should query AnnotationSet and so on. IQueryable means you can query the store with LINQ expressions.

For access you need only this code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk;
using System.ServiceModel.Description;
using service-namespace;

namespace CrmConsoleApplication2 {
    class Program {
        private static IOrganizationService _service;
        private static OrganizationServiceProxy _serviceProxy;

        static void Main(string[] args) {

            IServiceConfiguration<IOrganizationService> orgConfigInfo =
                ServiceConfigurationFactory.CreateConfiguration<IOrganizationService>(new Uri("http://server/company-name/XRMServices/2011/Organization.svc"));
            var creds = new ClientCredentials();

            using (_serviceProxy = new OrganizationServiceProxy(orgConfigInfo, creds)) {

                // This statement is required to enable early-bound type support.
                _serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());

                _service = (IOrganizationService)_serviceProxy;

                List<Account> acc;
                using (context srv = new context(_service)) {
                    acc = srv.AccountSet.Where(a => a.AccountId != null).ToList();

Account a1 = acc[0]; a1.Name = a1.Name + ” mod mod”; Account a2 = acc[1]; a2.Name = a2.Name + ” mod mod”; srv.UpdateObject(a1);
srv.UpdateObject(a2); srv.SaveChanges();
}
} } } }

And this is what you get @ runtime :

crm2011 accessing accounts wcf service

This indeed is a stupid examle with not checking if there is something at position 0 and 1 but I just wanted to modify something on my account. After modification of account you should call UpdateChanges each object you modified and then to save changes to CRM you should call SaveChanges. All changes will be processed at once.

You should also wrap OrganizationServiceProxy and also contex with using, because they both use IDisposable interface. Calling .ToList() after where on AccountSet will trigger downloading of all entities.

Please be aware, that downloading many objects will create big response from server (just for example 6000+ of our customized account objects created aproximately 180MB response (tracked by fiddler) and my console app expanded to 700MB in RAM when parsing and 500MB after loading all objects).

To create and delete record, you can use snippet like this :

                    Account newaaa = new Account();
                    newaaa.Name = "test acc";

                    srv.AddObject(newaaa);
                    srv.SaveChanges();

                    Account newAcc = srv.AccountSet.Where(a => a.Name == "test acc").FirstOrDefault();
                    srv.DeleteObject(newAcc);
                    srv.SaveChanges();

This will create new account, when invoking SaveChanges after AddObject, object newaaa will be filled with guid of freshly created Account. To delete object you have to “download” new object from service, you can’t use newaaa object, because context isn’t tracking the changes, so it can’t delete the object also.

In case of any questions, just mail me or add comment under the article.