Wednesday, September 21, 2011

CRM 2011 – Custom Workflow Syntax changes from CRM 4 to CRM 2011 « Hosk's Dynamic CRM 2011 Blog

Usefull post from The Host on differences between CRM 4 and CRM 2011 custom workflow actions.


Differences in Custom Workflow Assembly in CRM 4.0 and CRM 2011


We have listed the list of changes noticed for designing a custom workflow assembly in CRM 2011 and in CRM 4.0.


1. References


CRM 4.0


using System.Workflow.Activities;


using System.Workflow.ComponentModel;


using System.Workflow.ComponentModel.Compiler;


using Microsoft.Crm.Sdk;


using Microsoft.Crm.Sdk.Query;


using Microsoft.Crm.SdkTypeProxy;


using Microsoft.Crm.Workflow;


CRM 2011


using System.Activities;


using Microsoft.Crm.Sdk.Messages;


using Microsoft.Xrm.Sdk;


using Microsoft.Xrm.Sdk.Workflow;


2. Base Class


Base class definition has been changed from SequenceActivity to CodeActivity.


CRM 4.0: In CRM 4.0 we have to specify both Workflow name and Workflowactivitygroupname in the code as written in the following code.


[CrmWorkflowActivity("My Custom Workflow", "CRM Workflow")]


public class MyCustomWF: SequenceActivity


CRM 2011: In CRM 2011 that is done in different way.


public class MyCustomWF: CodeActivity


Both Workflow name and Workflowactivitygroupname can be specified at the time of registering the assembly as shown in below screen shot.


3. Execute Method


The overridden Execute method remains the same except parameter and return type.


CRM 4.0


protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)


CRM 2011


protected override void Execute(CodeActivityContext executionContext)


4. Create service


CRM 4.0


IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));


IWorkflowContext context = contextService.Context;


ICrmService crmService = context.CreateCrmService();


CRM 2011


IWorkflowContext context = executionContext.GetExtension();


IOrganizationServiceFactory serviceFactory = executionContext.GetExtension();


IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);


5. INPUT Parameters


CRM 4.0


Declaration: how to initialize the input parameter


// specified dependency property


public static DependencyProperty CaseIDProperty = DependencyProperty.Register("CaseID", typeof(Lookup), typeof(TotalTaskRetrieval));


// Specified Input property


[CrmInput("Enter Case ")]


// Set the reference Target for Property created


[CrmReferenceTarget("incident")]


// Property Defined for caseId


public Lookup CaseID


{


get


{


return (Lookup)base.GetValue(CaseIDProperty);


}


set


{


base.SetValue(CaseIDProperty, value);


}


}


Use: Access the input parameter declared above as,


Guid caseid=CaseID.Value


CRM 2011


Declaration: how to initialize the input parameter


[Input("Enter Case ")]


[ReferenceTarget("incident ")]


[Default("3B036E3E-94F9-DE11-B508-00155DBA2902", " incident ")]


public InArgument CaseID { get; set; }


Use: Access the input parameter declared above as,


Guid caseid = CaseID.Get(executionContext).Id


6. OUTPUT Parameters


CRM 4.0


[CrmOutput("outputSum")]


public CrmMoney Sum


{


get


{


return (CrmMoney)base.GetValue(SumProperty);


}


set


{


base.SetValue(SumProperty , value);


}


}


CRM 2011


[Output("outputSum")]


[Default("23.3")]


public OutArgument Sum { get; set; }

Tuesday, June 07, 2011

What does that website look like in different web browsers?

I have recently come across this nifty little website called BrowserShots where you can test your web design in different browsers.

http://browsershots.org/

This is great for web designers and web developers alike who need to save time and see what a particular website looks like on other peoples computers.

It is a free open-source online service and when you submit your web address, it will be added to the job queue.  A number of distributed computers will open your website in their browser. Then they will make screenshots and upload them to the central server so you can see what your website looks like on different browsers.  Its really nifty!

Browsers supported include Internet Explorer, Epiphany, Firefox, Galeon, Iceweasel, Konqueror, Opera and Safari and on different platforms including Mac and PC.

Thursday, May 19, 2011

Nunit GUI Runner > Reload on test assembly change > Re-Run the tests

Generally I run all my tests from within Visual Studio triggered by some add-in such as Resharper or TestDrive.Net , however have been unable to get SpecFlow tests/specs executing with the VS IDE, hence I've returned to NUnit GUI runner to execute my tests.

I stumbled across a neat option in the NUnit Gui Runner yesterday and thought it was noteworthy as it's handy to know during test development.  Each and every time my tests change and I build the test assembly we can get the Nunit Gui Runner to reload the test assembly and then re-run.  NUnit has some options

Under the NUnit settings > Test oader > Assembly Reload, tick all the tick boxes

Test Loader Settings - Assembly Reload

Assembly Reload

If Reload before each test run is checked, a reload will occur whenever the run button is pressed whether the assemblies appear to have changed or not.

If Reload when test assembly changes is checked, assemblies are watched for any change and an automatic reload is initiated. This item is disabled on Windows 98 or ME.

If Re-run last tests run is checked, tests are re-run whenever a Reload takes place.

Nunit GUI Runner Settings - Test Loader Settings

 

 

Thursday, May 05, 2011

Web Test Frameworks

I've spent some time looking around for some decent test frameworks for the CRM User Interface.  I want to test that certain things change, or update, as a result of workflow, security rights or javascript.

Ideally I would like to:
- Record the test in IE from  my CRM 2011 dev environment 64bit operating system
- Export the test to C#
- Be able to run the tests from Visual Studio 2010 via the Reshaper Test Runner

I've not been able to find a suitable fit for free, but here's some note worthy frameworks I found at the time of writing.

Selenium 

Selenium seems to be one of the better frameworks out there, it has many plug-ins, tests can be recorded (in FireFox only) and scripted to a lot of languages, and can run the tests across many different browsers.  Unfortunately not being able to record the tests in IE means that this is not ideal for my requirements.

WatiN  and Test Record

WatiN seems to be the next best thing if you need to record tests using IE, there's a Watin Test Recorder that allows you to record and export the tests in to C# and other languages, this sounds great but unfortunately it's not compatible with 64bit operating systems which means it can't be used for CRM 2011.  I did post a comment to a feature request to get it working with 64bit operating systems so there's hope yet.

Robot Framework 

The Robot Framework with an add-in called the SeleniumLibrary also looks promising. Robot framework is a keyword-based testing framework that is written in python. It allows you to write test cases in plain text or as html tables. SeleniumLibrary is an extension that lets you script web pages with keywords like Open Browser, Click Link, Checkbox Should Be Selected, etc.  The downside to this is that you can't record the tests and then edit them.


So with no perfect fit I'm going to have to change my requirements
. I suspect that I will find that I will get more value and more robust tests if you code them myself.

Both the Robot Framework, and Selenium seem to be good bets, both are large projects with a lot of support and activity on them.   Unfortunately test recording and VS test running don't seem to be options with the frameworks.  Long term my money is on the Robot Framework but today its .Net integration is not really there.  I came across a project called Selenium Toolkit for .NET
 that simplifies the setup and use of the functional testing framework Selenium, while I'm unable to get the tests to run from Visual Studio/Reshaper at this point, I'm sure it's possible.

For a comprehensive list of open source testing frameworks look here

Friday, December 10, 2010

Stability issues with AsyncRemoveCompletedJobs

Stability issues with AsyncRemoveCompletedJobs: "CRM 4.0 UR 3 brought in a useful feature, the ability to configure the CRM Asynchronous Service to automatically delete records from completed asynchronous operations, and hence keep the size of the asyncoperationbase SQL table down to a reasonable size. This behaviour is configured by the registry values AsyncRemoveCompletedJobs and AsyncRemoveCompletedWorkflows

However, I recently met an issue with this behaviour, where the CRM Asynchronous Service appears to get in a state where all it is doing is deleting completed jobs, to the exclusion of all other activity. This can leave the CRM Asynchronous Service to have effectively hung (not responding to service control requests, nor polling for new jobs to process) and not to process any new jobs for a considerable period of time (in one environment, this could be several hours).

The main symptoms are:

  • No jobs being processed for a considerable period of time
  • The Crm Asynchronous Service not responding to service control requests (i.e. you cannot stop it through the Services console, so you have to kill the process)
  • No values reported for most performance counters (e.g. 'Total Operations Outstanding', 'Threads in use')
  • If you do restart the service, you see a burst of activity (including performance counters) whilst outstanding jobs are processed, then it reverts to the same behaviour as above
  • If you look at the SQL requests submitted by the Crm Asynchronous Service (I use the SQL dynamic management views sys.dm_exec_requests and sys.dm_exec_sessions) you see just one DELETE request and no other SQL activity

At the moment, the only workaround I have is to remove the registry values, and to use a scheduled SQL job to periodically clear out the asyncoperationbase table. Here is an example of such a script.

"

Monday, October 25, 2010

Unit test 'internal' methods?

I'm building a class library that has some public and internal methods and I want to unit test some of the internal methods, from an external test assembly.  This is an age old problem that I've never found a good solution to, until now.

It turns out from .Net 2 MS added a InternalsVisibleTo attribute into the framework. MSDNs description is "Specifies that types that are ordinarily visible only within the current assembly are visible to a specified assembly."

In order to use this attribute you need to add one line of code to your AssemblyInfo.cs class for each external assembly that needs to access internal methods.

[assembly: InternalsVisibleTo( "My.UnitTest.Assembly.Name" )]

It's simple and very clean. We are declaring in our target assembly that our test assembly is a Friend Assembly.

Thursday, July 22, 2010

Javascript: Succinct Set Lookup value

The CRM 4 SDK for setting a lookup is very verbose and this post shares a simpler way to set a lookup value.

The following code example from the SDK shows how to set values in a field of type Lookup.
//Create an array to set as the DataValue for the lookup control.
var lookupData = new Array();
//Create an Object add to the array.
var lookupItem= new Object();
//Set the id, typename, and name properties to the object.
lookupItem.id = '{1AAC1363-01A1-DB11-8432-0003FF9CE217}';
lookupItem.typename = 'account';
lookupItem.name = 'A Bike Store';
// Add the object to the array.
lookupData[0] = lookupItem;
// Set the value of the lookup field to the value of the array.
crmForm.all.parentaccountid.DataValue = lookupData;

Things to note above are that we create an array instance and the an object instance. The Javascript language provides a short hand way of creating instances of these classes.

The Object shorthand allows us to replace the lookupItem variable (defined in lines 4 to 8 above) with the following:
{id:'{1AAC1363-01A1-DB11-8432-0003FF9CE217}', 
 typename:'account',
 name:'A Bike Store'}

We can create an array instance by using square brackets [] so lookupData (defined in lines 2 and 10) could become:
[lookupItem]

Putting all together we can remove both the variables in the example and use the following instead:
crmForm.all.parentaccountid.DataValue = [{ 
 id:'{1AAC1363-01A1-DB11-8432-0003FF9CE217}', 
 typename:'account', 
 name:'A Bike Store'}];
In conclusion the shorthand makes a lot cleaner code once you understand the JavaScript shorthand notation

Tuesday, March 23, 2010

CRM Sharing Data across Microsoft Dynamics CRM Deployments

Nice white paper on Sharing Data across Microsoft Dynamics CRM Deployments, this is particularly relevant for one of my clients where it is  impractical to meet all their business requirements within a single CRM organisation.

Overview
The ability to share data across Users, Teams, and Business Units within a single organization is provided by Microsoft Dynamics CRM 4.0 “out-of-the-box.” Administrators can provide users with differing levels of access to the data stored in CRM based on the roles, privileges, teams and Business Unit settings associated with specific users.
While using a single CRM instance is probably the simplest way to accommodate the data sharing needs within an organization, using multiple instances of Dynamics CRM may be preferable in a number of scenarios.
Consider the following reasons for using multiple instances of Microsoft Dynamics CRM:
  • Organizational Scale, to accommodate large volumes of users or data, or heavy processing
  • Geographical Distribution, to allow users to work against local rather than remote instances of CRM
  • Divisional or partner segregation, to limit the data that is distributed and the levels of access that each instance has
  • Legal requirements, to ensure that data is retained in a specific local geography This paper is focused on sharing data across multiple CRM organizations, which can occur at three distinct levels: Front-End / User Interface Level, Application Level, or Data Level.

This paper is not intended to serve as a solution guide, but rather to assist Microsoft Dynamics CRM architects with designing and implementing solutions to meet the needs of specific business scenarios.

Thursday, March 18, 2010

CRM 4 Import Customisations error "There is insufficient system memory in resource pool 'internal' to run this query."

I ran into the below error when importing customisations on to a new CRM 4 install, which had Server 2008 R2 and SQL 2008 on a virtual server with CRM Rollup 9 applied.


There is insufficient system memory in resource pool 'internal' to run this query


Googling only confused me as I develeved into many SQL fourms.  In the end the solution was really simple.  I'd inadvertantly only allocated 1GB of memory to the machine.  I doubled the memery and the import was sucessfull.




Prior to this issue, I also got the below error during the import:

Could not import a Saved Query {5ADB1DD1-2F93-4C65-AC0A-2372E3EAD103} for ObjectTypeCode 9100 because this is a system Saved Query. The Entity you are trying to import is not the same as the one existing in the database even though it has the same name.

Entity 9100 is the report entity, omitting the entity from the import stopped the issue, but I assume this means that you cannot import the report entity from Rollup 7 customisations export to Rollup 9 CRM instance.

Wednesday, March 17, 2010

CRM 4 Import Export Customisations cool tool

I've lost day working out why my CRM customisations have been corrupted because a custom attribute has changed datatype. I've spent hours working out what the exact customisation need to be exported to bring UAT in line with Dev. I've gone cross eyed deleting attributes that are no longer used.  

But no more this tool solves these problems and more, totally awesome, look at at it's features:



  • Console Application, Making it possible to import and export inside nant, msbuild or bat scripts, for example to export the customization each night and “check in” to a source code repository, enabling version control of the customizations. Also to import customizations directly from a MSI installation.
  • Export Only Modifications, You can export a “clean” customization xml in the beginning of a project and save it in the application folder as “CleanCustomization.xml”, the application will compare the current state and only export the entities that are modified or added.
  • Remove Deleted Attributes, This feature only applies when importing a customization. When this operation is selected one will be prompted with all attributes that has been removed in the new customization, given the possibility to remove them from the CRM instance.
  • Changes Attribute data type, When changing an attributes data type and then trying to import it to a CRM instance that still contains the old attribute would normally generate an error. This is now handled and the data inside the old attribute will be converted to the new data type (when possible and logical)
  • Publish, You can publish the customizations, can also be used at it’s own, for example assigning it to a system wide hotkey for fast access.
  • Node & Entity Selection, you can select what nodes and entities to import and export. For example only export ISV Config or the Site Map. Possible items to select, 


EntitiesWorkflowsRolesISV Config
SitemapTemplatesCalendar SettingsGeneral Settings
Email SettingsMarketing SettingsOutlook SynchronizationAutoNumbering Settings
And more…





  • JavaScript Export/Import, This allows you to extract JavaScript to a local folder, where you can work in a proper script editor, and later import them back. You can also create new javascripts in the same folder, just follow the name convention and they will also be imported to the correct entity / event.
  • Zip support, Now all features works with zipped customizations
  • Include Related Entities, This features will automatically include related entities to the selected entities, so their relationships are exported and can be reviewed for conflicts. This is recommended during the development process when relationships may change.
  • Publish Workflows, Publish operation now also publishes workflows