Mobile Express for Microsoft Dynamics CRM 4.0 is available as a free download. It supports all the customization and the multi-tenant capabilities of Microsoft Dynamics CRM 4.0. Customization tools are embedded within Mobile Express for Microsoft Dynamics CRM 4.0, and it uses the same user roles that you already have to provide a role-based experience on the device.
http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=f592ec6c-f412-4fd5-9a80-cd3bcbd26d8b#tm
Overview
As you all know a CRM lookup only displays its related entity primary field. Although this can not be changed using existing customizations; in most cases that suffices.
However, there are occasions where you want to display another information in order to avoid opening the related entity form.
So I created a generic JavaScript function to display another attibute inside CRM lookup.
Sample
On a contact form you want to display the accountnumber field, inside the parent customer lookup, instead of primary field of the account entity.
Before:
After:
Step 1
Go on the form where the lookup is displayed:
On the onload event, add this line of code and change LookupSchemaName by the schema name of your lookup.
| crmForm.all.LookupSchemaName.FireOnChange(); |
Step 2
On the onchange event of the lookup, Copy the following code (inside the table):
- fieldToDisplay = the name of the attribute that you want to display in the lookup. Take the schema name of the attribute in the linked entity.
- fieldToDisplayIsText:
- true if you want to display a nvarchar field.
- false if you want to display a picklist or a lookup field.
- organizationName = name of your organization (without spaces).
| var fieldToDisplay = 'accountnumber'; var fieldToDisplayIsText = true; var organizationName = 'MyOrganizationName'; var lookupData = new Array(); var lookupItem= new Object(); var lookup = event.srcElement.DataValue; if (typeof(lookup) != 'undefined' && lookup != null && lookup[0] != null) { var myValue = GetAttributeValueFromID(lookup[0].typename,lookup[0].id,fieldToDisplay,fieldToDisplayIsText); if(myValue != '') { lookupItem.id = lookup[0].id; lookupItem.typename = lookup[0].typename; lookupItem.name = myValue; lookupData[0] = lookupItem; crmForm.all[event.srcElement.id].DataValue = lookupData; } } function GetAttributeValueFromID(sEntityName, sGUID, sAttributeName, isTextField) { var xml = "" + "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" + GenerateAuthenticationHeader() + " <soap:Body>" + " <Execute xmlns=\"http://schemas.microsoft.com/crm/2007/WebServices\">" + " <Request xsi:type=\"RetrieveRequest\" ReturnDynamicEntities=\"false\">" + " <Target xsi:type=\"TargetRetrieveDynamic\">" + " <EntityName>" + sEntityName + "</EntityName>" + " <EntityId>" + sGUID + "</EntityId>" + " </Target>" + " <ColumnSet xmlns:q1=\"http://schemas.microsoft.com/crm/2006/Query\" xsi:type=\"q1:ColumnSet\">" + " <q1:Attributes>" + " <q1:Attribute>" + sAttributeName + "</q1:Attribute>" + " </q1:Attributes>" + " </ColumnSet>" + " </Request>" + " </Execute>" + " </soap:Body>" + "</soap:Envelope>" + ""; var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP"); xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false); xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/Execute"); xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); xmlHttpRequest.setRequestHeader("Content-Length", xml.length); xmlHttpRequest.send(xml); var result = null; if(isTextField){ result = xmlHttpRequest.responseXML.selectSingleNode("//q1:" + sAttributeName).text; } else { result = xmlHttpRequest.responseXML.selectSingleNode("//q1:" + sAttributeName).getAttribute('name'); } if (result == null) { return ''; } else return result; } |
Step 3
Save and publish the entity
PAF
Hi,
I share you the last version of the ‘CRM search gadget‘. We need beta testers to improve the tool. You can download it here.
This gadget was created to win time of search in CRM(especially during incoming phone calls). Only one Input to retrieve any entities.
CRM Guide
Because this kind of tool is very useful/interesting for WW CRM Community, we decided (with Remi and Kelvin) to create a generic solution. So You can use it in your company without coding anything.
You can easily personalize your own parameters in the gadget. If you have to add one entity or attributes to request on CRM.
Technologies Involved: Silverlight 2.0 RTM and CRM 4.0 Web Services.
OS: Vista and Windows Seven
Known issues: Doesn’t work on 64 bits OS
Installation: Double click on MSCRM.gadget file (here).
We’re waiting for feedbacks on design, functionalities and bugs !!!
Should you have any questions, please feel free to add a comment.
See you soon
PAF, Kelvin and Rémi
==============================================
Part 1 - Gadget UI
Step 1 – Enter what you’re looking for
Here, we’re looking for ‘Symtrax’ data in CRM

Step 2 – Result Panel

To copy data in your clip board, just click on labels.
Part 2 – Settings UI
‘CRM’ Tab
Here, you’ll be able to change the CRM target
‘Search’ Tab
Select entities and attributes you want to request.

‘Show’ Tab
Select entities and attributes you want to display in the result panel.

We've done the best to keep the installation Easy for all of you.
Download file here
Prerequisites:
Client Side:
- Mandatory: Silverlight
- Facultative: Office communicator, Internet Connection
Server Side:
- Mandatory: Create a picture field on the contact entity
Step 1: Create the picture field on the contact entity
Annotation: Silverlight can only display JPEG and PNG files, so don't try to indicate a gif file.
We enable the possibility to display contacts picture, so we created an additional attribute on the contact entity :
Name: Picture Url
Schema Name: new_pictureurl
Type: nvarchar
Format: Text
Maximum Length: 250
This field only contains pictures url as we cannot stored image in MD CRM 4.0.
- You must customize the contact entity. For that, go to “settings” section in left menu and Click on “customization”, then on “customize entities”. You must have a security role including "System Customizer"
- Double click on Contact Row

- Select the "attributes" section and click on the "new" button.
- Create a new attribute with the following properties :
Name: new_pictureurl
Type:
nvarchar
- Add this new field on the contact form and publish contact entity
Step 2: Move the Silverlight application on your MD CRM 4.0 web site
Download the application here. Unzip the file and copy the carousel folder on your CRM Server "<serverroot>\ISV" folder.
Step 3: Add link to the carousel in the CRM site map
Exporting the Site Map
- In the Navigation Pane, click Settings, click Customization, and then click Export Customizations.
- In the View drop-down, select Client Extensions.
- In the list, select Site Map.
- Click Export Selected Customizations and then click OK to close the notice about information that may be exported.
- Click Save and save the customizations.zip file to a location of your choice.
- Click Close. .
Now, decompress the zip file and open the customizations.xml file in your XML Editor (Visual Studio in my case)
- Here is a sample group to add below an Area: Just change the server name
<Group Id="Addons" Title="Addons">
<SubArea Id="nav_carousel" Title="Carousel" Icon="/_imgs/qfinddown.gif" Url="http://[serverName]/ISV/Carousel/carousel.html" Client="Web" PassParams="1"
/>
</Group>
After you modify the Site Map element in the customizations.xml file, you import the modified customizations.xml file to apply changes
Importing the Site Map
- In the Navigation Pane, click Settings, click Customization, and then click Import Customizations.
- Click Browse to locate an XML file or a compressed (.zip) file that contains customizations and settings exported from Microsoft Dynamics CRM.
- Double-click the file or select the file, and then click Open.
- Click Upload.
Step 4: Try the carousel
Refresh your browser and click on the link previously added :
We're waiting for your feedbacks
Some weeks ago, we decided to built a Silverlight Application to show contacts in a carousel. Because one idea never comes alone, we added link with Virtual Earth and OCS.
The installation is very easy, less than 10 minutes.
The installation guide is here. And you can download the carousel here.
Functionality Overview : (there are some animations during actions, so lets try this on your environment)
- Display all my contacts with pictures and there locations via Virtual Earth. You also can check the availability of your contact with the Office Communicator status.
We can display the CRM carousel as home page like that:
or in an account form:
- I can directly call a contact by clicking on his phone number: Office Communicator integration. I also can start an instant message in Office communicator by clicking on the status.
- I can directly send an email by clicking on the envelop and open the contact form by clicking on 'Details':
We're waiting for your comments/feedbacks for the next release. Currently, we're working to improve the first loading.
PAF
Here is a sample code to add a button into CRM contact form which will push contacts in Outlook. JavaScript code inside this button takes contact info and adds it directly in Outlook. We've done it for demonstration, this is a base to improve. Fullname field is the index to check duplicate contacts

All is done in the ISV.config file.
The source code has been done to work with Outlook 2007 and CRM 4.0.
Two Prerequisites: Once an Outlook 2007 application is installed on the system and the security setting is done as per above, we are ready to use this feature
- Since we need to create Outlook contact on the client-side, we will be using an ActiveX object. Thus, we need to enable the setting to allow ActiveX scripts, as shown below (found under Security Settings of Internet Options):
![clip_image001[6]](http://blogs.msdn.com/blogfiles/paf/WindowsLiveWriter/AddacontactinOutlookfromaCRMcontactform_E9B/clip_image001%5B6%5D_thumb.jpg)
For demonstration, I prefer set my CRM Web Site as 'trusted sites'
and 'Enable' - Initialize and script ActiveX controls not marked as safe for scripting.
- Outlook 2007 installed on client machines
The ISV Config Part :
| <ImportExportXml version="4.0.0.0" languagecode="1036" generatedBy="OnPremise"> <Entities> </Entities> <Roles> </Roles> <Workflows> </Workflows> <IsvConfig> <configuration version="3.0.0000.0"> <Root /> <Entities> <Entity name="contact"> <ToolBar ValidForCreate="0" ValidForUpdate="1"> <Button JavaScript=" var outlookApp = new ActiveXObject('Outlook.Application'); var nameSpace = outlookApp.getNameSpace('MAPI'); var contactFolder = nameSpace.getDefaultFolder(10); var firstname = ''; var lastname = ''; var fullname = ''; if(crmForm.all.firstname != null && crmForm.all.firstname.DataValue != null) { firstname = crmForm.all.firstname.DataValue; fullname = firstname; } if(crmForm.all.lastname != null && crmForm.all.lastname.DataValue != null) { lastname = crmForm.all.lastname.DataValue; if(fullname != '') fullname += ' '; fullname += lastname; } if (fullname != '' && contactFolder.Items.Find("[FullName] = '" + fullname + "'") == null) { var contact = outlookApp.CreateItem(2); contact.FullName = fullname; contact.FirstName = firstname; contact.LastName = lastname; if(crmForm.all.emailaddress1 != null && crmForm.all.emailaddress1.DataValue != null) contact.Email1Address = crmForm.all.emailaddress1.DataValue; var ar = new Array(); if(crmForm.all.parentcustomerid != null && crmForm.all.parentcustomerid.DataValue != null) { ar = crmForm.all.parentcustomerid.DataValue; contact.CompanyName = ar[0].name; } if(crmForm.all.mobilephone != null && crmForm.all.mobilephone.DataValue != null) contact.MobileTelephoneNumber = crmForm.all.mobilephone.DataValue; if(crmForm.all.telephone1 != null && crmForm.all.telephone1.DataValue != null) contact.BusinessTelephoneNumber = crmForm.all.telephone1.DataValue; if(crmForm.all.jobtitle != null && crmForm.all.jobtitle.DataValue != null) contact.JobTitle = crmForm.all.jobtitle.DataValue; if(crmForm.all.fax != null && crmForm.all.fax.DataValue != null) contact.BusinessFaxNumber = crmForm.all.fax.DataValue; if(crmForm.all.address1_city != null && crmForm.all.address1_city.DataValue != null) contact.BusinessAddressCity = crmForm.all.address1_city.DataValue; if(crmForm.all.address1_stateorprovince != null && crmForm.all.address1_stateorprovince.DataValue != null) contact.BusinessAddressState = crmForm.all.address1_stateorprovince.DataValue; if(crmForm.all.address1_postalcode != null && crmForm.all.address1_postalcode.DataValue != null) contact.BusinessAddressPostalCode = crmForm.all.address1_postalcode.DataValue; if(crmForm.all.address1_country != null && crmForm.all.address1_country.DataValue != null) contact.BusinessAddressCountry = crmForm.all.address1_country.DataValue; var address = ''; if(crmForm.all.address1_line1 != null && crmForm.all.address1_line1.DataValue != null) address += crmForm.all.address1_line1.DataValue; if(crmForm.all.address1_line2 != null && crmForm.all.address1_line2.DataValue != null) address += ' ' + crmForm.all.address1_line2.DataValue; if(crmForm.all.address1_line3 != null && crmForm.all.address1_line3.DataValue != null) address += ' ' + crmForm.all.address1_line3.DataValue; contact.BusinessAddressStreet = address; contact.Save(); alert('Contact creation succeed'); } else { alert('already exist'); } " Client="Web"> <Titles> <Title LCID="1036" Text="Add contact in Outlook" /> </Titles> <ToolTips> <ToolTip LCID="1036" Text="Add contact in Outlook" /> </ToolTips> </Button> </ToolBar> </Entity> </Entities> </configuration> </IsvConfig> <EntityMaps /> <EntityRelationships /> <Languages> <Language>1036</Language> </Languages> </ImportExportXml> |
Hope this helps
PAF
During our developments, we got some issues. Here, you’ll find tips to solve them. This is for people that are already familiar with both Silverlight and CRM.
1 - First Problem: authentication headers are not being set when using the Silverlight generated proxy. So the aim was to inject headers into the request ‘on the fly’.
There is an easy way to do it in SilverLight via custom chanels : OperationContextScope (System.ServiceModel).
To allow you to use CRM web service in SL, you have to add the class ‘MyCrmAuthenticationTokenSerializer’ in your code and call it to push crm authentication header in the request.
void Page_Loaded(object sender, RoutedEventArgs e)
{
CrmServiceSoapClient crmService = new CrmServiceSoapClient();
crmService.RetrieveCompleted += new EventHandler<CRMSilverlight.CrmSdk.RetrieveCompletedEventArgs>(crmService_RetrieveCompleted);
using (new OperationContextScope((IContextChannel)crmService.InnerChannel))
{
//here, we inject the CRM Authentication header
//The Xml formater is just to prevent some characters from being encoded (otherwise CRM can't parse the authentication token properly)
MessageHeader header = MessageHeader.CreateHeader("CrmAuthenticationToken", "http://schemas.microsoft.com/crm/2007/WebServices", "", new MyCrmAuthenticationTokenSerializer(0, "MyCrmOrganization", null));
// Insert SOAP header
OperationContext.Current.OutgoingMessageHeaders.Add(header);
crmService.RetrieveAsync("account", new Guid("1EB30C87-EA80-DD11-AE35-00155DA20A01"), cols);
}
}
//Result
void crmService_RetrieveCompleted(object sender, CRMSilverlightDirect.CrmSdk.RetrieveCompletedEventArgs e)
{
try{
TextBlock tb = new TextBlock();
account myAccount = (account)e.Result;
tb.Text = myAccount.name;
LayoutRoot.Children.Add(tb);
}
catch (Exception ex)
{
string wtf = ex.Message;
}
}
//You have to add this class to generate the CRM authentication header
public class MyCrmAuthenticationTokenSerializer : XmlObjectSerializer
{
int _authType;
string _organizationName;
string _callerId;
public MyCrmAuthenticationTokenSerializer(int authType, string organizationName, string callerId)
{
_authType = authType;
_organizationName = organizationName;
_callerId = callerId;
if (_callerId == null)_callerId = "00000000-0000-0000-0000-000000000000";
}
public override void WriteStartObject(XmlDictionaryWriter writer, Object graph)
{}
public override void WriteObjectContent(XmlDictionaryWriter writer, Object graph)
{
string authToken = string.Format("<AuthenticationType xmlns='http://schemas.microsoft.com/crm/2007/CoreTypes'>{0}</AuthenticationType><OrganizationName xmlns='http://schemas.microsoft.com/crm/2007/CoreTypes'>{1}</OrganizationName><CallerId xmlns='http://schemas.microsoft.com/crm/2007/CoreTypes'>{2}</CallerId>", _authType, _organizationName, _callerId);
writer.WriteRaw(authToken);
}
public override void WriteEndObject(XmlDictionaryWriter writer)
{}
public override bool IsStartObject(XmlDictionaryReader reader)
{
return true;
}
public override Object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
{return null; }
}
2 - Second Problem: Not all columns were returned when you use the strongly typed entity based classes in Silverlight.
The problem is that response comes back with non ordered attributes and that makes the SL proxy to null some values. It’is important to notice that the CRM service doesn’t return values for null fields.
The solution: By using DynamicEntity you are by-passing the custom serialization so you should continue to work moving forward.
For your information: the strongly typed entity based classes are deprecated so using DynamicEntity is the correct approach to pursue.
Hello,
My name is Pierre-Adrien FORESTIER aka PAF, I'm Partner Technical Specialist on MD CRM since 3 years @ Microsft France I've just created this blog to share reusable and useful developments around Microsoft Dynamics CRM 4.0.
With my colleague Kelvin Lonfat, we're programming a lot of tools and we will publish some articles very soon.
Firstly, we plan these articles :
1 - How to Comsume CRM Web Services from a WCF client like Silverlight applications
2 - Silverlight reports in MD CRM 4.0 by using the visifire(http://www.visifire.com/) library.
3 - Silverlight Carousel linked to Live map, OCS and MD CRM 4.0.
4 - A generic Vista Gadget to search Data in CRM 4.0.
5 - A lot of tips to develop in JavaScript with CRM 4.0.
6 - ...
So, Stay tuned
PAF

Resource Page Description
This VSTO 2008 Outlook sample Add-in will show you an interesting implementation of the OBA concept.
First aim is to grab information from the Active Directory on the emails' senders to display their name, title, phone number and picture. Thanks to that, you will then establish quick VO/IP calls or chat sessions using unified communication provided by Exchange 2007 and Communicator 2007. Moreover, being able to discover the face of your colleagues is something really cool!
Second aim is to extract details from a Microsoft Dynamics CRM 4.0 base for external emails. It will help you to gain a lot of time as you'll have access almost in real time on information about your customers and partners. Moreover, you'll also be able to give them a call in a single click via VO/IP just after having received their emails.
Technologies used in this sample:
- VSTO 3/Visual Studio 2008 SP1
- Outlook 2007
- WPF & ElementHost to display the pictures on a 3D animated cube (thanks to the Fluidkit library : http://www.codeplex.com/fluidkit)
- Microsoft Dynamics CRM 4.0 WebService
- Background Workers to do the resolving job on a second thread
- System.DirectoryServices
Check out my blog : http://blogs.msdn.com/davrous for screenshots and pointers to MSDN articles explaining how this add-in works and how to set it up on your own environment.
A French MSDN article with a video is available here: http://msdn.microsoft.com/fr-fr/cc948938.aspx . This article explains how it works, the basic architecture of the add-in and how to setup this add-in against your own CRM 4.0 environnement.
David Rousset