CRM 2013 – Create Enumerations for option sets

What are enumerations for option sets I hear some of you thinking?

start with early bound classes.

I mentioned the benefits of early bound classes in my blog post CRM 2015 – Typescript is ready to go, definition files available on NuGet

Early bound code is creates a wrapper class round your entities.  It includes all the fields in your entity.  The benefits of early bound classes

  • No typos
  • no type errors
  • easy to read and understand code

Early bound code means a lot of the potential errors in the CRM code are found at compile time instead of run time.  The big advantage of this is most of the errors are found and fixed by the developer rather than being found by the end customer.

Microsoft have a good post – Use the early bound entity classes in code

The advantages to using early-bound entity classes is that all type references are checked at compile time. The compiled executable contains the code necessary to invoke the types’ properties, methods, and events. For more information, see Use the early-bound entity classes for create, update, and delete.

Early bound classes create an entities file which includes all the names and types of the fields

The benefit of early bound code is you remove syntax errors and bring all type errors into  compile time and not runtime, so your customers don’t see them.

You can type things like this


Contact contact = new Contact();
contact.FullName = "Marvellous Hosk"

Rather than


Entity contactEntity = New Entity()

contactEntity["Fullname"] = "Marvellous Hosk"

You will notice full name is typed incorrectly, this error would only appear when the plugin is run because the compiler cannot check the late bound code for syntax errors.

What are Enumerations for option sets?

Enumerations for option sets are what early bound code is to entities.

Creating enums for option sets helps get rid of magic numbers which is a code smell .  A magic number is where code uses a number value with no explanation what the number is.  The end result is confusing code which is hard to understand.

More reasons why magic numbers are bad

  • It’s hard to maintain
  • Difficult to understand
  • change nightmare if numbers are used in many places

CRM options set and statuses are  a classic breeding ground for magic numbers to magically spring up in code.

A kind-hearted developer who hasn’t learnt thought about using enums for optionsets might create a field called StatusReasonClosed = 9100000 or they might put a comment.

This is not a bad way but it involves manually creating the variables and brings in the possibility of different naming conventions, it’s better to automate the process and use enums.  Below you can see an example of a magic number and a enum.

if (incident.StatusCode.Equals(6))
{
//do something incident cancelled
}

or

if (incident.StatusCode.Equals(incident_statuscode.Canceled))
{

//do something incident cancelled

}

Creating the option set enums file

You have a few options for creating option set enums.  The easiest tool to use is

CRM Early Bound Generator

I reviewed the tool in the link below

CRM 2013 Tool – CRM Early Bound Generator

The screen shot below shows you why it’s great, it has a lovely GUI interface.

The option set values will create a file enums like this


[System.Runtime.Serialization.DataContractAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("CrmSvcUtil", "6.1.0001.0123")]
public enum incident_statuscode
{

[System.Runtime.Serialization.EnumMemberAttribute()]
InProgress = 1,

[System.Runtime.Serialization.EnumMemberAttribute()]
OnHold = 2,

[System.Runtime.Serialization.EnumMemberAttribute()]
WaitingforDetails = 3,

[System.Runtime.Serialization.EnumMemberAttribute()]
Researching = 4,

[System.Runtime.Serialization.EnumMemberAttribute()]
ProblemSolved = 5,

[System.Runtime.Serialization.EnumMemberAttribute()]
InformationProvided = 1000,

[System.Runtime.Serialization.EnumMemberAttribute()]
IncidentComplete = 100000000,

[System.Runtime.Serialization.EnumMemberAttribute()]
IncidentWithdrawn = 100000001,

[System.Runtime.Serialization.EnumMemberAttribute()]
Canceled = 6,

}

To use the optionset.cs file you need to copy it into your visual studio project with your CRM plugins.  You can then use the enums instead of statecode and statuscode which will make your code easier to understand.

Potential problems with Existing Option set enums

I added some status reasons, the next step was to regenerate the OptionSet.cs file with the enums in.

I did this using the CRM  early bound generator tool, I copied the file to the project in visual studio, rebuilt the project and then I got loads of errors.

The CRM early bound generator create enum with this title

new_contributionrequest_new_ContributionStatus

but the enums used in the code was like this

new_contributionrequestnew_ContributionStatus

The question was how did they previously create the optionset enums? To the internet

Searching the internet I came to the this page

Create extensions for the code generation tool

It seems Microsoft had create a class library you could call via the command line to create option set enums.

The code is bundled with the CRM SDK

SDK\SampleCode\CS\CrmSvcUtilExtensions\GeneratePicklistEnums

You have to open the project in visual studio, build it

This will then put the files into the debug\bin

SDK\SampleCode\CS\CrmSvcUtilExtensions\GeneratePicklistEnums\bin\Debug

You then need to modify the bat file called GenerateOptionSets.bat and change the url setting to point to your CRM instance (don’t forget to add the orgname of the CRM organisation you want to create the optionset enums for)

CrmSvcUtil.exe ^
/codewriterfilter:”Microsoft.Crm.Sdk.Samples.FilteringService, GeneratePicklistEnums” ^
/codecustomization:”Microsoft.Crm.Sdk.Samples.CodeCustomizationService, GeneratePicklistEnums” ^
/namingservice:”Microsoft.Crm.Sdk.Samples.NamingService, GeneratePicklistEnums” ^
/url:http://CRMSERVER/ORGNAME/XRMServices/2011/Organization.svc ^
/out:OptionSets.cs

This created the OptionSet file in the same format as the previous.

If I was starting a new project I would use the CRM early bound generator

 

 

Advertisement

CRM 2011/CRM2013 – Investigating a casting error with ActivityParty

I was getting an odd error whilst casting a CRM dynamics spell, no it wasn’t a spell it was casting an ActivityParty to an Entity (although some people might say ActivityParty is rather magic or at least very complex)

Talking of bad casting, this would have been terrible

Burt Reynolds as Han Solo in Star Wars

 

Casting Error

error in getproduct Unable to cast object of type ‘Microsoft.Xrm.Sdk.Entity’ to type ‘Hosk.Dynamics.Entities.ActivityParty‘.

It was on a plugin on the ServiceAppointment entity.  What I was trying to do, is when the user updated the ServiceAppointment Entity.  I would check the resources (which can either be a user or equipment).

If it’s equipment, I can then look up the value of a product and show a few product details on the ServiceAppointment record.

I was using early bound records but when I tried to get the serviceAppointment.Resources I got a casting error.

The odd thing was I could step through the code calling it from a console app but I was getting an error when the plugin was running.

The error was so odd I had to get someone to look at my code to check if I was doing a schoolboy error.

I knew it wasn’t a problem the Resources field was empty because I was checking it, it definitely had a value, the only problem was I got an error every time I tried to get it.

 

Finding the Error

 

To find the error, first I changed the code to throw an InvalidPluginException and this then puts out my tracing lines in the plugin.  Which is good because I recently blogged about mocking up tracing and have been using tracing whilst debugging some plugins

CRM 2011 – You can now add tracing to your plugins

CRM 2011/2013 – using ITracingServicing and Mocking it up

So using the tracing line I could work out where the problem was occuring and see the casting error – FACE to FACE with the beast

The question was what value was in the resources field?

Debugging with the Plugin Registration tool

I used the plugin registration tool to set profiling on my ServiceAppointment then this spits out a file with all the serialized field values.  You can then use this file to rerun the code in the Plugin Registration tool and attach the debugger to the plugin registration tool.

This is a lot better method than remote debugging because remote debugging stops the CRM server from running, so can hold up other developers/testers on that CRM instance

Here is a good article if you need to use the Plugin Registration tool for some debugging

http://blog.sonomapartners.com/2013/03/debugging-crm-2011-plugins-with-the-plugin-profiler.html

I finally got to the ServiceAppointment.Resources, instead of a List of ActivityParty I found it had this

This was the line causing the casting error

 List<ActivityParty> resources = (List<ActivityParty >)serviceAppointment.Resources.ToList();

The error it was throwing was this

System.Linq.Enumerable.CastIterator<Ntt.Dynamics.Crm.HondaPLCC.Entities.ActivityParty>

Now that I was stepping through the code, I could have a look at the Entity attribute and retrieve the Resources value using Late bound code and this worked fine.

 

var entities = ((EntityCollection)  entity[serviceAppointment.GetAttributeName(x => x.Resources)]).Entities; 
                ActivityParty resources = null; 

                if (entities. Any())
                {
                    var firstOrDefault = entities. FirstOrDefault();
                    if (firstOrDefault! = null)
                        resources = firstOrDefault. ToEntity< ActivityParty>();}
                

 

So the error was linked to the early bound class and there is some problem with it.

I had already spent way to much time writing this simple plugin, so I just used the work around getting the value from the Entity class and used late bound methods to get the data.

I did think about correctly the entities file but this would have been overwritten when anybody refreshed the early bound entities.  So I decided to go with the code above and retrieve the resources using the early bound entity.

 

Plugin Registration tool

Using the plugin registration tool is an excellent way to debug plugins on a server but it can be done on your local machine, so it doesn’t impact the other developers working on the project.

All CRM Developers should know about the Plugin Registration tool, I mention this because some new CRM Developers have never used the Plugin Registration tool because they only deploy plugins using the CRM Developer toolkit.

So dust off the plugin registration tool and go a bit old school on your CRM.

CRM 2011/2013 – System.InvalidCastException: Unable to cast object of type ‘Microsoft.Xrm.Sdk.Entity’ to type

I had an odd error today whilst developing and it turned out to be a very frustrating few hours.

I was writing a plugin which would work for Lead and Contact and because of this I was using a mixture of late binding and early binding.

The late binding was used because I was writing a plugin to fire on update and create of a lead/contact. It was working out the salutation. It was different entities but the same field names.

So I used Entity object and late binding to get the values of a 2 field, I was using these values to retrieve the data from another entity which was early bound.

My personal preference is to use early binding because I find the code is easier to read, it’s also a lot easier to  write because you can use intellisense to get the fields rather than looking at the exact field name.  The other benefit of early binding is you remove any syntax errors from run time and casting/conversion errors are found whilst compiling.

 

Casting error

It was working fine, my queryexpression was returning some records but when I tried to cast the records from Entity to my early bound entity I was getting

System.InvalidCastException: Unable to cast object of type ‘Microsoft.Xrm.Sdk.Entity’ to type…

Now this is a common problem people have had with early bound types

Usually to resolve the problem you need to add one of the lines below to say, yes – enable ProxyTypes for my CRMService (IOrganizationService)

_serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
_serviceProxy.EnableProxyTypes();

But looking at my code I could see I already had this

 

Duplicate Entities Reference

Then whilst building the project I was getting this error

Duplicate ‘Microsoft.Xrm.Sdk.Client.ProxyTypesAssemblyAttribute’ attribute

What the heck does this mean, more internet searching

This brought me to this page

and an answer from CRM MVP Gonzalo

Reference assemblies are not supported in CRM (at least officially) and they can always cause headaches, I strongly discourage them. What you can do is include the generated code from crmsvcutil.exe into each of your plugin assemblies and that should work. You can also include this line of code in your plugin assembly (which is included in the generated code):

It seems the problem was due to someone trying to reference Entities class from inside a dll and this doesn’t really work and a better solution is to add the entities class, so it’s included in the plugin dll (and you don’t need to go outside to another DLL to get the entities.class)

Visual Studio pointed me to this line with it’s error

[assembly: Microsoft.Xrm.Sdk.Client.ProxyTypesAssemblyAttribute()]

I then noticed I had two references to Entities (early binding file)

using Hosk.Dynamics.Crm..Entities;
using Microsoft.Xrm.Sdk.Query;
using Hosk.Dynamics.Crm..ContactLead.Entities;

 

Now things started to become clear, when I looked at the entities file before it didn’t have the entity I wanted so I regenerated the entities file using the CRM Developer toolkit.

The downside of using the CRM Developer toolkit to do this is it creates an entities file for all of them.  I did notice before there only seemed to be a small selection of the entities.

I then found there was a separate project with the crmsvcutil.exe, for those of you who don’t know what this is, it’s the command line tool Microsoft has created for creating the early bound Entities file.

I have used and written about this before

https://crmbusiness.wordpress.com/2011/01/29/crm-2011-simple-crmsvcutil-example-for-creating-early-bound-classes/

https://crmbusiness.wordpress.com/2011/02/24/crm-2011-how-to-add-crmsvcutil-to-the-external-tools-menu-in-visual-studio/

 

Only Create the Entities you need

The crmsvcutil.exe takes some config values which allows you to specify which entities you want to create early binding for.

You can pass some variables to the exe

<?xml version=”1.0″ encoding=”utf-8″ ?>

<configuration>
<appSettings>
<add key=”o” value=”Entities.cs“/>
<add key=”url” value=”http://<CRM Server url/>CRMORGNAME/XRMServices/2011/Organization.svc“/>
<add key=”namespace” value=”Hosk.Entities”/>
<add key=”codewriterfilter” value=”BasicFilteringService,CrmSvcUtilExtensions”/>
</appSettings>
</configuration>

 

Then a text file called EntitiesToBuild.txt and in this file were all the entities we wanted to build early bindings for.

This is great stuff, it’s efficient because it creates early bound data only need the early bound entities you use in the code.  Limiting the entities you create the early bound entities file will save you time creating/refreshing the entities file and reduce the size of plugin dll’s.

Missing References

I added in my entity, ran the crmsvcutil.exe but then suddenly I got loads of errors.  A previous developer had created the entities file but hadn’t updated the EntitiesToBuild so I was missing a bunch of entities which used early binding.

I added these entities in and then I got some error with fields missing.

One of the plugins was no longer being used and many of the fields it was using had been deleted.

 

Finally it compiled and I was up and running again, I had forgotten what I was actually doing.

 

Early Bound Generator

The solution for creating the early bound classes worked, there is now a tool which can do it for you, so you don’t have to spend any time using the crmsvcutil with the command line.

The tool is the Early Bound Generator and has a nice GUI interface for you, I have reviewed it on a previous blog/video

https://crmbusiness.wordpress.com/2014/05/13/crm-2013-tool-crm-early-bound-generator/

here is a link to the codeplex site

https://xrmearlyboundgenerator.codeplex.com/

 

The tool has been  improved since my initial review.  I will also proudly add the Hosk CRM blog is the link which brings the most traffic to the codeplex site and mentioning it here may even send a bit more traffic towards over that way, not to mention I love CRM tools.

If you want to see the other CRM tools I have reviewed click the link below

https://crmbusiness.wordpress.com/hosks-microsoft-dynamic-crm-development/crm-2013-tools/

 

Why should I care about this error

It’s true you probably won’t get the error in the same scenario as above but it’s useful to know about this casting error and the cause.

If you ever see errors about casting Microsoft.Xrm.Sdk.Entity type to a custom entity type then you know there is some problem with the entities file.

Often the problem is the entities file is not up to date/not the latest version as I discussed in the blog post below earlier this week

Error – the source file is different from when the module was built

So as soon as you see this error, you know it’s an early bound/Entities problem.