CRM 2013 Quick View Menu iPad Support

Quick View Menu now supports IPad Safari and has also improved display on smaller resolutions with heights of 768px. IE8+ is also now supported along with earlier versions of Chrome and FireFox.

Available from CodePlex – http://crm2013quickviewmenu.codeplex.com/

QuickViewMenuOOB

Form Message for Dynamics CRM

Download Form Message for Dynamics CRM on Codeplex

The form message solution can be found on CodePlex, it allows you to place custom messages onto a CRM form where you can define text and the image icon such as Success, Error, Information, Warning and Alert.

You can also choose to display the 2 buttons that can be customised with your desired label for example OK, Cancel, or Submit, Cancel, etc… and attach JavaScript functions as call back events for each one.

Form Message with Buttons displayed
Form Message with buttons.png

Available Message Icons

alert_16.png error_16.png info_16.png success_16.png warning_16.png

Adding Form Message web resource to CRM Form
WebResource on Form.png

You can add initial/static text and an icon by supplying Custom Parameters such as text and type like this.

WebResource on Form Custom Parameters.png

Usage

Form Message Functions include

showFormMessage(message, type, iFrame, iframeLoadedCallback)
setFormMessageVisible(iFrame, isVislble)
showMessageConfirmation(iFrame, successCallBack, cancelCallBack, successLabelOverride, cancelLabelOverride)

Form Message Types include

success
alert
warning
error
info

Display Form Message

DXTools.FormMessage.showFormMessage("This is a test Message.", "success", "WebResource_HeaderMessage", function () { });

Display Form Message with Buttons

DXTools.FormMessage.showFormMessage("This is a test Message.", "info", "WebResource_HeaderMessage", function () {
        DXTools.FormMessage.showMessageConfirmation("WebResource_HeaderMessage", function () { alert("yes") }, function () { alert("no"); }, null, null);
    });
});

Download Form Message for Dynamics CRM on Codeplex

Dynamics CRM Discovery and Web Service URLs

Dynamics CRM Discovery and Web Service URL’s based on the following Dynamics CRM SDK articles.

Discover the URL for your organization with IDiscoveryService web service

Download the endpoints using the Dynamics CRM Developer resources page

Here is the information that you need:

For CRM Online customers:

The following URLs should be used to access the discovery service (use the appropriate URL for your location):

Provider: Microsoft Office 365
https://disco.crm.dynamics.com/XRMServices/2011/Discovery.svc (North America)
https://disco.crm4.dynamics.com/XRMServices/2011/Discovery.svc (EMEA)
https://disco.crm5.dynamics.com/XRMServices/2011/Discovery.svc (APAC)

Provider: Microsoft Account
https://dev.crm.dynamics.com/XRMServices/2011/Discovery.svc (North America)
https://dev.crm4.dynamics.com/XRMServices/2011/Discovery.svc (EMEA)
https://dev.crm5.dynamics.com/XRMServices/2011/Discovery.svc (APAC)

The following URLs should be used to access the Organization service(SOAP endpoint):

https://{Organization Name}.api.crm.dynamics.com/XrmServices/2011/Organization.svc (North America)
https://{Organization Name}.api.crm4.dynamics.com/XrmServices/2011/Organization.svc (EMEA)
https://{Organization Name}.api.crm5.dynamics.com/XrmServices/2011/Organization.svc (APAC)

Where {Organization Name} refers to the Organization that you specify in the URL when accessing the Web application. For example, for Contoso.crm.dynamics.com, the {Organization Name} is Contoso.

The following URLs should be used to access the Organization Data service(OData REST endpoint)

https://{Organization Name}.api.crm.dynamics.com/XrmServices/2011/OrganizationData.svc (North America)
https://{Organization Name}.api.crm4.dynamics.com/XrmServices/2011/OrganizationData.svc (EMEA)
https://{Organization Name}.api.crm5.dynamics.com/XrmServices/2011/OrganizationData.svc (APAC)

For On-premise
deployments:
http://{server}/XRMServices/2011/Discovery.svc for the Discovery service endpoint
http://{server}/{OrgName}/XRMServices/2011/Organization.svc for the Organization Service endpoint (SOAP)
http://{server}/{OrgName}/XRMServices/2011/OrganizationData.svc for the Organization Data Service endpoint (REST)
http://{server}/XRMDeployment/2011/Deployment.svc for the Deployment Service endpoint

For IFD deployments:

http://dev.{hostname[:port]}/XRMServices/2011/Discovery.svc for the Discovery service endpoint

CRM 2013 Quick View Menu Performance Improvements

Besides some tweaking here and there with the async processing, image pre-loading and so forth, there is a new feature to turn on or off the recently added security feature. The current security feature uses the user’s security privileges to determine if a button is displayed and an entity button will only display if they have the Read access right to the specific Entity. Turning off the security feature prevents the Quick View Menu from making a number of web requests which may improve load performance.

Available from CodePlex – http://crm2013quickviewmenu.codeplex.com/

This is an example of the Quick View Menu Solution Configuration page. Simply click the Security button to toggle security on or off.

QuickViewConfigWithSecurity

Training & Adoption Kit for Microsoft Dynamics CRM 2013

The Microsoft Dynamics Customer Center has published an article providing useful links to help you create your own training material. The Training and Adoption Kit for Microsoft Dynamics CRM 2013 provides links to several editable eBooks and help files that you can customize. You can use this material for your own purposes which may include replacing images and screen shots, modifying the text, inserting your company logo and aligning it with your own business standards and style guides. There are also a few help orientated videos you can watch to learn more about Dynamics CRM 2013.

Take a look and hopefully you can take advantage of this material. http://www.microsoft.com/en-us/dynamics/crm-customer-center/training-adoption-kit-for-microsoft-dynamics-crm-2013.aspx

CRM 2013 Quick View Menu with Multi-browser Support

The Quick View Menu helps you navigate to any location in Dynamics CRM quickly and seamlessly by taking your existing Sitemap and presenting it in an easy to navigate interface. The menu currently comes with a Win 8 UI look & feel while also allowing you to provide additional resource and configuration settings.

Multi-browser support tested with IE10+, Chrome, FireFox. Other browsers should work and this will be confirmed in the near future. If you have any issues with any browser please provide feedback.

Available from CodePlex http://crm2013quickviewmenu.codeplex.com/

QuickViewMenuOOB

Microsoft Dynamics CRM 2013 Announcement

Today Microsoft has announced that it will make the new version of CRM, titled Dynamics CRM 2013,  available in fall 2013 (Spring in the southern hemi). Very exciting news and I’m sure many people are going to be getting very excited over the next months as more information becomes shared publically.  Read the MS News Center article here for information http://www.microsoft.com/en-us/news/Press/2013/Jul13/07-02DynamicsCRM13PR.aspx

Additional info

Microsoft Dynamics CRM customers and prospects can learn more about Microsoft Dynamics CRM at http://www.microsoft.com/en-us/dynamics/crm-vision.aspx.

Microsoft Dynamics CRM partners can follow the launch at https://mbs.microsoft.com/partnersource/solutions/CRM/CRMLaunchPage.htm.

You can follow and engage with the Microsoft Dynamics CRM community @MSDynamicsCRM, http://www.twitter.com/msdynamicscrm.

CRM Online to SharePoint Online Integration using REST and ADFS

Accessing SharePoint Online 2013 REST services with SSO via ADFS (Active Directory Federation Services) from CRM Online provides loads of potential opportunities, especially now that SharePoint offers a huge REST API. You can call REST from a CRM Online Plugin or Custom Workflow activity with no dependencies on SharePoint Client dll’s or Azure getting in the way, It is fairly awesome I must say.

I use the HttpWebRequest class to perform SOAP requests to perform the authentication part of this integration, which is totally supported within Sandboxed Plugins and Custom Workflow Activities. You can read more about the restrictions of the CRM Sandboxed environment here http://msdn.microsoft.com/en-us/library/gg334752.aspx. Once you get authenticated and obtain the cookies you are free to fire REST calls off by simply providing the cookies along with the request.

The best diagram I found to describe the authentication process visually was from Wictor Wilen’s blog http://www.wictorwilen.se/

Auth Process

I wanted to explore the issue of authentication between CRM Online and SharePoint Online from a server to server perspective and as you can imagine authentication is a big hurdle for this direct type of communication as every example I have seen so far includes Azure. Well at least until I started to look at what others were doing with Windows 8 Apps and Active Authentication. Omar Venado http://blogs.msdn.com/b/omarv/ and fellow MVP Wictor Wilen http://www.wictorwilen.se/ had some really great articles to help me build out a solution focused on this scenario. The code attached to this blog is heavily derived from Omar’s Windows 8 App code though now is useable in non Windows 8 App projects such as C# Console, SSIS Packages and of course CRM Plugin/Workflow projects. I have added some background reading at the bottom of this post so you can see the articles I used to get my code to work.

An example of how simple this code is to use

Uri spSite = new Uri(https://myOrg.sharepoint.com/sites/mySite”);

bool success = SpoAuthUtility.Create(spSite, username@domain.com, WebUtility.HtmlEncode(“Pword123″), false);

string odataQuery = “_api/web/lists”;

Uri url = new Uri(String.Format(“{0}/{1}”, SpoAuthUtility.Current.SiteUrl, odataQuery));

// Send a json odata request to SPO rest services to fetch all list items for the list.

byte[] result = HTTPHelper.SendODataJsonRequest(

url,

“GET”, // reading data from SP through the rest api usually uses the GET verb

null,

(HttpWebRequest)HttpWebRequest.Create(url),

SpoAuthUtility.Current // pass in the helper object that allows us to make authenticated calls to SPO rest services

);

string response = Encoding.UTF8.GetString(result, 0, result.Length);

You can authenticate using corporate credentials if inside your network, username/password if outside your network (e.g CRM Online O365) and you can also use your onmicrosoft.com accounts. Remember that my primary focus was on server to server integration possibilities, not user to server contexts such as in the current SharePoint CRM List Component model.

The attached C# Console app contains 3 files to provide you with an example of how to use the 2 cs classes HTTPHelper and SPOAuthUtility. To authenticate and start calling REST from CRM Plugins/Workflows simple include the HTTPHelper and SPOAuthUtility cs files into your Plugin/Workflow project.

Example App is available here https://skydrive.live.com/redir?resid=492A170E77E43399!830

Background reading

http://blogs.msdn.com/b/omarv/archive/2012/10/25/windows-8-store-apps-office-365-enterprise-preview-sharepoint-online.aspx

http://blogs.msdn.com/b/omarv/archive/2012/11/15/developing-windows-store-apps-for-sharepoint-online-with-sso-single-sign-on.aspx

http://www.wictorwilen.se/Post/How-to-do-active-authentication-to-Office-365-and-SharePoint-Online.aspx

http://allthatjs.com/2012/03/28/remote-authentication-in-sharepoint-online/

CRM 2011 SDK version 5.0.16 available

The MS CRM Team have released an updated CRM 2011 SDK version 5.0.16 which can be downloaded here http://www.microsoft.com/en-us/download/details.aspx?id=24004 or viewed on MSDN here http://msdn.microsoft.com/en-us/library/gg309408.aspx Check out the SDK Release History notes here http://msdn.microsoft.com/en-us/library/dn198205.aspx

 

What’s Changing in the Next Major Release – This new topic outlines features that will be changing in the upcoming Orion release and provides a tool you can use to help you prepare your organizations for these changes.

 

New and updated topics Description of changes
Microsoft_Dynamics_CRM_2011_SDK_Readme.htm Updated the readme for this version of the SDK package.
Active Directory and Claims-Based Authentication

Authenticate Office 365 Users with Microsoft Dynamics CRM Online Web Services

OrganizationServiceProxy

DiscoveryServiceProxy

Updated these topics to remove the restriction on using the service proxy classes when authenticating with the Microsoft online services identity provider of Microsoft Dynamics CRM Online. You can now use these proxy classes with all deployment types and identity providers.
BulkDeleteRequest

BulkDetectDuplicatesRequest

Added in Remarks that you can run the bulk delete job or bulk detect duplicates job daily or without recurrence.
Create, Export, or Import an Unmanaged Solution

Create, Install, and Update a Managed Solution

Added a note to these topics saying “Installing a solution can interfere with normal system operation. We recommend that you schedule solution imports when it’s least disruptive to users.”
Form XML Reference The following FormXml elements have been updated to indicate that they are for internal use only: <ControlMode> (FormXml), <QuickFormRelationshipName> (FormXML), <QuickFormRelationshipRoleOrdinal> (FormXml), and <UniqueId> (FormXml). These elements are used only in a quick form, which is not customizable. These elements will be removed from the schema in the next major release.
Handle Exceptions in Plug-Ins Clarified how plug-in exceptions are handled and where error message are written or displayed.
Introduction to Activity Feeds Corrected the maximum number of characters in the posts created programmatically. The correct value is 2000 characters.
Introduction to Solutions Added the Enterprise Solution Lifecycle Management section introducing the ALM for Microsoft Dynamics CRM 2011: CRM Solution Lifecycle Management white paper.
Open Forms, Views, Dialogs and Reports with a URL Appended to an existing note to include:

Microsoft Dynamics CRM forms are not designed to be opened as dialogs using either showModalDialog or showModelessDialog.

Uninstall or Delete a Solution Added an Access the Solutions List with a URL section.
What’s Changing in the Next Major Release Added a new topic to provide information about what is changing in the next major release of Microsoft Dynamics CRM.
Write Custom Code for Microsoft Dynamics CRM for Outlook

GoOffline               GoOnline

Added a note that these methods cannot be used in a plug-in because they cause a UI interaction with the user.
Xrm.Page.data.entity Attribute Methods Added a missing getFormat return value: textarea.
Xrm.Page.ui Control Methods Added a remark to the addCustomView method to show that this method does not work with Owner lookups.
Xrm.Utility Reference Corrected an error for the openEntityForm method. This method returns a Boolean value rather than a window object.

CRM 2011 Validate User Security Roles using JavaScript/REST

This example I’m sharing today is demonstrating a few techniques which promote JavaScript and REST, along with using namespaces and creating a library of functions/properties. This example declares a library Security.UserInRole and defines a number of properties and functions. The general idea is to allow the data access via REST to be asynchronous which then offers a valid and invalid function callback option to be defined to handle the outcome. You can specify an array of security roles to check against the current user and then with the callback functions you can perform the actions that you require.

Ideally I want to call a function that is easy to use and it will look like this.
Security.UserInRole.checkUserInRole(
["System Administrator", "System Customizer", "Custom Role Name"],
function(){alert("valid"); // The user is in one of the specifed roles.
},
function(){alert("invalid"); // The user is not in one of the specifed roles.
}
}

To define the library namespace and object we use
//If the Security namespace object is not defined, create it.
if (typeof (Security) == "undefined")
{ Security = {}; }
// Create Namespace container for functions in this library;
if (typeof (Security.UserInRole) == "undefined") {
Security.UserInRole = {
__namespace: true
};
}

 

The library functions and properties declared include the following
Security.UserInRole = {
isInRole: null,
roleIdValues: [],
validFunction: null,
invalidFunction: null,
checkRoles: [],
checkUserInRole: function (roles, validFunc, invalidFunc) {},
getAllowedSecurityRoleIds: function () {},
validateSecurityRoles: function () {},
querySecurityRoles: function (queryString) {},
__namespace: true
};

 

The entire library is implemented so that you call a function, it performs the processing asynchronously and then gives you the outcome to handle the response. Whether you want to show/hide form elements or disable fields etc, you can handle this in the callback function parameters validFunc and invalidFunc defined in the checkUserInRole function. The entire library content can be placed in a CRM webresource and added to a form. The full library is as shown below.

//If the Security namespace object is not defined, create it.
if (typeof (Security) == "undefined")
{ Security = {}; }
// Create Namespace container for functions in this library;
if (typeof (Security.UserInRole) == "undefined") {
Security.UserInRole = {
isInRole: null,
roleIdValues: [],
validFunction: null,
invalidFunction: null,
checkRoles: [],
checkUserInRole: function (roles, validFunc, invalidFunc) {
validFunction = validFunc;
invalidFunction = invalidFunc;
checkRoles = roles;
Security.UserInRole.getAllowedSecurityRoleIds();
},
getAllowedSecurityRoleIds: function () {
var filter = "";
for (var i = 0; i < checkRoles.length; i++) {
if(filter == "") {
filter = "Name eq '" + checkRoles[i] + "'";
}
else {
filter += " or Name eq '" + checkRoles[i] + "'";
}
}
Security.UserInRole.querySecurityRoles("?$select=RoleId,Name&$filter=" + filter);
},
validateSecurityRoles: function () {
switch (Security.UserInRole.isInRole) {
//If the user has already been discovered in role then call validFunc
case true:
validFunction.apply(this, []);
break;
default:
var userRoles = Xrm.Page.context.getUserRoles();
for (var i = 0; i < userRoles.length; i++) {
var userRole = userRoles[i];
for (var n = 0; n < Security.UserInRole.roleIdValues.length; n++) {
var role = Security.UserInRole.roleIdValues[n];
if (userRole.toLowerCase() == role.toLowerCase()) {
Security.UserInRole.isInRole = true;
// Call function when role match found
validFunction.apply(this, []);
return true;
}
}
}
// Call function when no match found
invalidFunction.apply(this, []);
break;
}
},
querySecurityRoles: function (queryString) {
var req = new XMLHttpRequest();
var url = "";
// Try getClientUrl first (available post Rollup 12)
if (Xrm.Page.context.getClientUrl) {
url = Xrm.Page.context.getClientUrl();
}
else {
url = Xrm.Page.context.getServerUrl();
}
req.open("GET", url + "/XRMServices/2011/OrganizationData.svc/RoleSet" + queryString, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null; //Addresses memory leak issue with IE.
if (this.status == 200) {
var returned = window.JSON.parse(this.responseText).d;
for (var i = 0; i < returned.results.length; i++) {
Security.UserInRole.roleIdValues.push(returned.results[i].RoleId);
}
if (returned.__next != null) {
//In case more than 50 results are returned.
// This will occur if an organization has more than 16 business units
var queryOptions = returned.__next.substring((url + "/XRMServices/2011/OrganizationData.svc/RoleSet").length);
Security.UserInRole.querySecurityRoles(queryOptions);
}
else {
//Now that the roles have been retrieved, try again.
Security.UserInRole.validateSecurityRoles();
}
}
else {
var errorText;
if (this.status == 12029)
{ errorText = "The attempt to connect to the server failed."; }
if (this.status == 12007)
{ errorText = "The server name could not be resolved."; }
try {
errorText = window.JSON.parse(this.responseText).error.message.value;
}
catch (e)
{ errorText = this.responseText }
}
}
};
req.send();
},
__namespace: true
};
}

 

To use the library in the onload event of an entity form simply add the Security.UserInRole library webresource to the form and create a another JavaScript web resource to hold the onload function. The onload function may look like this. You define the roles to check as an array and pass this to the checkUserInRole function along with the valid and invalid callback functions. You don’t have to define the functions as anonymous functions like my example below but it can sometimes feel cleaner.

function onload()
{
Security.UserInRole.checkUserInRole(
["System Administrator", "System Customizer", "Custom Role Name"],
function(){alert("valid"); // The user is in one of the specifed roles.
},
function(){alert("invalid"); // The user is not in one of the specifed roles.
}
);
}

 

I would like to mention Jim Daly from the MS CRM Team for his examples of namespace and library structure along with his REST query code as this example I have created is derived from his outstanding work.

Happy Coding..