Tuesday, December 3, 2013

CRM 2011 - Error updating System Settings (‘rdQuickFindRecordLimitEnabled’ is undefined)

Today i ran into an issue updating the System Settings (Auditing) in an upgraded RU14 system.

systemsettings-error

This happened when OK was clicked. The solution was to install RU15.

Hint: You need the installation cd/iso of CRM 2011 Server for the upgrade from RU14 to RU15.

Cheers

Monday, November 18, 2013

Simulate modem speeds / slow connection with Fiddler2

Last week i needed a possibility to simulate a very slow connection for testing the behavior of a web application. I found a nice feature integrated in Fiddler2.
Fiddler Modem Speed
Rules –> Performance –> Simulate Modem Speeds
It works very well for testing loadingscreens, progressbars, uploads and so on.
cheers
---
Update 2015-11-04
Scott Hanselman also wrote a nice post about this topic incl. integrated Chrome feature (Link).

Wednesday, October 23, 2013

CRM 2013 – Official Microsoft statement for jQuery usage

In the latest documentation you can find the document

Using jQuery with Microsoft Dynamics CRM 2013.docx

In this, Microsoft describes the prefered usage of jQuery in the Microsoft Dynamics CRM context.

Usage in HTML Webresources

Microsoft: When creating user interfaces with HTML web resources we highly recommend that you also use jQuery. It provides many benefits in creating pages that support multiple browsers that it is practically a necessity.

So this is fine and i think everyone is doing this right now.

Usage in Entity-Forms

Microsoft: However, when creating form scripts we do not recommend that you use jQuery. To enforce business logic in forms we provide objects in the Xrm.Page and Xrm.Utility namespaces that you use to apply your business logic within the form. We do not support referencing or manipulating the DOM (including styles) for our pages in any way. …

Ok, i have done this in the past and i don’t want to miss a lot of the jquery functions (ajax….) in the future too. So to make sure you don’t run into big issues try the following.

  • Avoid “hard” CSS/DOM Manipulation via jQuery

Microsoft: We reserve the right to restructure or rename DOM elements in our pages at any time without notice. If your code has dependencies on any objects defined in the DOM and these objects are reorganized or renamed your code will break.

  • Assuming you are not the only one who is delivering solutions for your customer, use the following construct to create your specific jQuery-Object ($).
   1: my$ = jQuery.noConflict(true);
   2: my$.trim("     some text with space     ");

Cheers

Tuesday, September 17, 2013

CRM 2013 – Create Custom Actions

The new version of Microsoft Dynamics CRM includes a feature called Custom Actions. In this post I want to show the process of creating an Action in the CRM UI and access it over a Console Application.

The Problem to solve:

Create a Custom Action, that creates a task or a phonecall for an existing account record, based on the “Industry” Optionset. It should also be possible to add the description of the task in the Request.

1. Create the Custom Action

In this example we create the action in the CRM UI. It is also possible to create it in Code (only OnPremise).

  • Navigate to Settings –> Processes

processes

  • Click “New” and set “CreateSalesActivities” as Process name
  • Set “Action” as Category
  • Select “New blank process”
  • Set “Account” as Entity
  • Click “OK”

action_screen_basic

  • Add the input parameter for Description

action_screen_input

  • Configure Ruleset

rules_for_action 

action_screen_ruleset_call

Accounting –> Create PhoneCall

action_screen_ruleset_task

Others –> Create Task

  • Save the Custom Action
  • Activate the Custom Action

activate_action 

2. Execute the Custom Action

For executing the Request i have created a Console Application. You can check the sources of my PluginQuickDeploy-Project when you need support creating it.

Executing Accounting-Case:

   1: private static void ExecuteCustomActionAccounting()
   2: {
   3:     IOrganizationService service = GenerateService();
   4:     Entity account = new Entity("account");
   5:     account.Attributes.Add(new KeyValuePair<string, object>("name",
   6:         string.Format("Account generated at {0}", DateTime.Now.ToShortTimeString())));
   7:     account.Attributes.Add(new KeyValuePair<string, object>("industrycode", 
   8:         new OptionSetValue(1)));
   9:     Guid accountId = service.Create(account);
  10:  
  11:     OrganizationRequest req = new OrganizationRequest("new_CreateSalesActivities");
  12:     EntityReference accountReference = new EntityReference("account", accountId);
  13:     req.Parameters.Add(new KeyValuePair<string, object>("Target", accountReference));
  14:     req.Parameters.Add(new KeyValuePair<string, object>("Description", "Text from Request"));
  15:  
  16:     OrganizationResponse resp = service.Execute(req);
  17: }

Executing Default-Case:



   1: private static void ExecuteCustomActionDefault()
   2: {
   3:     IOrganizationService service = GenerateService();
   4:     Entity account = new Entity("account");
   5:     account.Attributes.Add(new KeyValuePair<string, object>("name", 
   6:         string.Format("Account generated at {0}", DateTime.Now.ToShortTimeString())));
   7:     Guid accountId = service.Create(account);
   8:  
   9:     OrganizationRequest req = new OrganizationRequest("new_CreateSalesActivities");
  10:     EntityReference accountReference = new EntityReference("account", accountId);
  11:     req.Parameters.Add(new KeyValuePair<string, object>("Target", accountReference));
  12:     req.Parameters.Add(new KeyValuePair<string, object>("Description", "Text from Request"));
  13:  
  14:     OrganizationResponse resp = service.Execute(req);
  15: }


3. Testing


After execution of the both requests, a phonecall is generated and attached to the first account, a task is generated and attached to the second account. The description is passed by the request.


Created Call:


callCreated Task:


 task



Additional Information - Output Parameters


It is also possible to retrieve information from the custom action. Therefore you have to define Output-Parameters and set them in the rule wizard. In this example the Custom Action returns the Entity Reference of the created task.


return_value


assign_value_step


assign_value_rule


responseThe feature is very interesting and i look forward to use it in one of my next projects (lets hope CRM 2013 will be available and stable soon).


cheers

CRM 2013 – Custom Actions

Custom Actions are a feature shipped with CRM 2013. The easiest way to explain the feature (for developers) is:

You are able to create your own OrganizationRequest”

It is possible to use the CRM UI for creating an “Action” or you can write Code that creates a custom Action.

action_category

Key Points (SDK)

  • Is defined using a Workflow entity record, similar to a real-time workflow.
  • Can be associated with a single entity or be global, meaning not associated with any particular entity.
  • Is executed in the core operation stage 30 of the event execution pipeline.
  • Supports the invocation of plug-ins and real-time workflows registered in the pre-operation and post-operation stages of the event execution pipeline.
  • Can have plug-ins or real-time workflows registered in the pre-operation or post-operation stages while the action status is Draft.
  • Is available through the organization.svc and organization.svc/web endpoints, but not the organizationdata.svc (OData) endpoint.
  • Always runs under the security context of the calling user.
  • Record cannot be deleted while there are plug-in steps and other real-time workflows registered on the action.
  • Can be invoked only by a web service method call, not directly from a workflow. However, the workaround is to write a custom workflow activity that invokes the action and add that to a workflow.
  • Can optionally participate in the current database transaction.
  • Does not support a scope where the execution is restricted to a user, business unit, or organization.
  • Supports input and output parameters.
  • Supports auditing of data changes.
  • Is not supported with offline clients.

This feature will reduce plugin code in the future, because it is possible to encapsulate a sequence of operations in one request.

cheers

Monday, September 16, 2013

CRM 2013 – Business Rules

One of the new pretty interesting Features of Microsoft Dynamics 2013 are Business Rules. The purpose of them is to allow non Developers to customize basic rules like

  • Show and hide fields
  • Set and reset “Business Required” for fields
  • Show Error-Message
  • Set specific Field Value
  • Lock or unlock fields

on specific triggers/conditions. Also Basic-Formulas (+, –, *, /) are possible.

formula

The UI looks nice and clean (a bit like IFTTT).

Example

Set “Approved by Manager” Field as Business Required when Budget Amount of Opportunity is more than 50000,00€.

Before:

business_rule_before

Business Rule:

business_rule

After:

business_rule_after

Hint:

The Value for “Business Required” is not resetting automatically when Budget Amount is decreased to < 50000. An additional rule is required.

less_rule

This feature will reduce the lines of JavaScript code in the future enormously.

cheers

Thursday, September 12, 2013

CRM 2011 – ErrorCode=0x80041102 The entity with ObjectTypeCode –1 was not found in the MetadataCache

I ran into this problem on my last project. This issue only occurs on the productive system when someone is opening the solution (delivered by us). QA, Dev and so on worked fine.

We were able to solve this doing a good old IISReset.

There are a lot of other reasons for this (or nearly the same) error.

cheers

Simple reading of CSV Files - CsvHelper

In my last project we had to retrieve a huge amount of data from an existing CSV-File. I found a nice, fast, little library on GitHub called CsvHelper.


The easiest approach is to create a target class for this if the columns of the CSV-File does not match to the properties of your default business object.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.IO;
   4: using System.Linq;
   5: using System.Text;
   6:  
   7: using CsvHelper;
   8:  
   9: namespace MK.CsvExample
  10: {
  11:     class Program
  12:     {
  13:         static void Main(string[] args)
  14:         {
  15:             using (TextReader reader = File.OpenText(@"C:\tmp\Users.csv"))
  16:             {
  17:                 var csv = new CsvReader(reader);
  18:                 csv.Configuration.Delimiter = ";";
  19:  
  20:                 var usersFromCsv = csv.GetRecords<User>();
  21:  
  22:                 foreach (var user in usersFromCsv)
  23:                 {
  24:                     Console.WriteLine("{0} {1}, {2}, {3}, {4}",
  25:                         user.Firstname,
  26:                         user.Lastname,
  27:                         user.Street,
  28:                         user.City,
  29:                         user.Country);
  30:                 }
  31:             }
  32:             Console.ReadKey();
  33:         }
  34:     }
  35:  
  36:     /// <summary>
  37:     /// BusinessObject for getting CSV-Informations
  38:     /// Names needs to be the same as in the CSV-File
  39:     /// </summary>
  40:     public class User
  41:     {
  42:         public string Lastname { get; set; }
  43:         public string Firstname { get; set; }
  44:         public string Country { get; set; }
  45:         public string City { get; set; }
  46:         public string Street { get; set; }
  47:     }
  48: }

For usage of CSV-Files created in Excel, you have to change de Delimiter to a semicolon (see line 18).

csv-save

A NuGet package is also available: “PM> Install-Package CsvHelper”

cheers


Monday, September 2, 2013

Connect Scribe CRM Adapter to Microsoft Dynamics CRM Online

The official documentation for creating a connection between Scribe and Microsoft Dynamics CRM online seems not to be up to date.

The following configuration works fine.


It is important to use the discovery link as Server URL.

cheers

Scribe Certificates (Server / Microsoft Dynamics CRM Adapter)

Last week i have finished the Scribe-Certifications
  • Scribe Server Training
  • Scribe Adapter for Dynamics CRM
For preparation, i used the following training-sessions
  • Scribe Insight Overview
  • Workbench Training
  • Server Training
  • Adapter for Dynamics CRM Training
  • Integration for Dynamics GP and Dynamics CRM

The training material was very helpful and good to handle. You get a set of videos, a workbook with labs and a virtual machine (VMware) to complete the labs.

I recommend to use the official Scribe Documentation (.CHM) for doing the tests.

cheers

Wednesday, July 31, 2013

CRM 2013 No longer supported stuff

Following stuff is no longer supported in CRM 2013.
  • CRM 4.0 Custom Workflow Tools
  • CRM 4.0 Client Side Scripting
  • CRM 4.0 Plugins
  • 2007 WebService
  • ISV Folder
  • Solution Down Level Tool
Cheers

Monday, June 10, 2013

Visual Studio 2013 / Team Foundation Server 2013 Overview

Brian Harry posted a nice "2013" overview.

From my perspective, at the moment the most interesting features are

  • Nice UI Upgrade of TeamExplorer (Icons)
  • Solution-Overview in TeamExplorer
  • Pending Changes improvements
  • Testplan Management in WebUI
  • Team Rooms 

Cheers

Tuesday, May 28, 2013

CRM 2011 "unknown number prefix specified"-Exception on create of opportunity

This happens when you create a record with an already exisiting ID in CRM. In my example The first opportunity was created with ID1, the create-message of the second opportunity also contained the ID1 (typing mistake).



The Error-Message is a little bit meaningless...

Hope it helps.

Friday, February 8, 2013

Call custom WCF Soap Service from Javascript

In my posts regarding oData, you can find JavaScript calls against WCF DataServices. Here i describe the call against a default WCF SOAP Endpoint.

WCF Service:
  public class Service1 : IService1 {
      public string GetData(int value) {
          return string.Format("You entered: {0}", value);
      }
  }

JavaScript:
function Retrieve(id) {
 jQuery.support.cors = true;
 var soapData = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">' + '<s:Body><GetData xmlns="http://tempuri.org/"><value>200</value></GetData></s:Body></s:Envelope>';
 $.ajax({
     type: "POST",
     contentType: "text/xml; charset=utf-8",
     dataType: "xml",
     url: "http://localhost:58282/Service1.svc",
     data: soapData,
     beforeSend: function (xhr) {
       xhr.setRequestHeader("SOAPAction""http://tempuri.org/IService1/GetData");
     },
     success: RetrieveCallbackSuccess,
     error: RetrieveCallbackError
 });
}
function RetrieveCallbackSuccess(response) {     alert("Yey! :) --> " + response.text); }
function RetrieveCallbackError(err) {     alert("Onoz! :( --> " + err.statusText); }

The line "jQuery.support.cors = true" is important for cross domain requests.

Cheers,
Markus

Tuesday, February 5, 2013

CRM 2011 Instance Adapter - Connecting Organizations

I found a nice "little" application, released in december last year. It allows the connection of two Microsoft Dynamics CRM Instances (Organizations).

I have not tested it yet but it sounds very interesting for archiving or especially for Development Environments. Also Picklist-Values can be synced.

Microsoft Dynamics CRM 2011 Instance Adapter

There is also an Installation Video available.

Cheers,
Markus