Archive

Archive for January, 2009

Trust for Delegation in List Web Part for Microsoft Dynamics CRM 4.0

January 15, 2009 Leave a comment

This article pertains to Trust for Delegation issues encountered in on-premise installations of Microsoft Dynamics CRM 4.0 (MS CRM) when CRM server and SharePoint Server exist on different physical machines. If you have List Web Part (LWP) deployed for IFD version of MS CRM, or both Microsoft Dynamics CRM and SharePoint Server are on same machine then your deployment is not affected by the trust for delegations issue.

In scenarios, where MS CRM on-premise and SharePoint are setup on separate machines, Microsoft Dynamics users of LWP face issues during authentication. If the SharePoint Server is not setup for Trust for Delegation then the user’s Active Directory credentials are not passed to the MS CRM server. The LWP deployed on SharePoint does not receive the CRM authentication ticket from SharePoint and displays the sign on form used with an IFD installation. The screen below shows the configuration pane of LWP and sign on form. This form appears when a Trust For Delegation ( also known as Double-Hop impersonation ) is not present.

clip_image002

Figure 1 : IFD login from configuration pane

What is Double Hop issue?

In situations where SharePoint Server and MS CRM server are on different machines, the first hop is from the LWP user’s IE browser to the SharePoint server, and then from the SharePoint server to the MS CRM Server. This is the second hop. Windows credentials cannot be passed in second hop, due to security issues. To enable the SharePoint Server to pass the user credentials, the SharePoint server must be configured for Trust for Delegation.

Setting up ‘Trust for Delegation’

To make it easier to understand the configuration settings, consider the following topology:

  • Machine #1 Active Directory
  • Machine #2 SQL Server
  • Machine #3 Microsoft Dynamics CRM 4.0 Server
  • Machine #4 Windows SharePoint Services 3.0/Microsoft Office SharePoint Server 2007
  • Machine #5 User accessing SP using IE

 

clip_image004

Figure 2: Independent CRM and SharePoint Server topology

1. First, configure IIS and IE for delegation using the steps in following KB Article http://support.microsoft.com/default.aspx?scid=kb;en-us;810572

Note: To perform remaining steps , the user must be a member of the Domain Adminstrators group or the Enterprise Adminstrators group in Active Directory, or user must have been delegated the appropriate authority.

As a security best practice, consider using Run as to perform this procedure.

2. Click Start >> Control Panel >> Administrative Tools >> Active Directory Users and Computers.

3. In the console tree, click Computers.

4. In the details pane, right-click the computer you want to trust for delegation and then click Properties. In our case its Windows SharePoint Services 3.0 server or MOSS 2007 server (machine # 4 in figure 2) .

5. On the Delegation tab, click Trust this computer for delegation to specified services only.

clip_image005

Figure 3 : Trust for delegation to specific service

6. Depending upon the IIS authentication type in WSS/MOSS Web application, do one of the following:

  • If IIS authentication type is NTLM , Click Use any authentication protocol .

OR

  • If IIS authentication Setting is Integrated Windows authentication with Negotiate (Kerberos), click Use Kerberos only ( see figure 7 ).

7. Click Add and, in Add Services, click Users and Computers.

8. In Enter the object names to select (examples), type the name of the computer that the computer will be trusted to delegate for example, Dynamics CRM 4.0 computer (Server no 3 in figure 2) , and then click OK.

clip_image007

Figure 4 : Select User and Computers

If the machine name does not resolve, Click Advanced

  1.  
    •  
      • After opening Select Users or Computer dialog , click Find Now
      • Select CRM server computer from list and then click OK. In Select Users or Computer dialog , CRM server machine name will appear, Click OK.

clip_image009

Figure 5 : Select User and Computers using advanced dialog

9. In Add Services, click the Http service that will be trusted for delegation and click OK.

clip_image010

Figure 6 : Set trust for specified service

Notes

  • If you cannot see the Delegation tab as shown in Figure 3, do one or both of the following:
  •  
    • Register a Service Principal Name (SPN) for the computer account using the Setspn utility in the support tools that are on your CD. Delegation is only intended to be used by service accounts, which should have registered SPNs, as opposed to a regular user account which typically does not have SPNs.
    • Raise the functional level of your domain to Windows Server 2003 .
  • Constrained delegation, delegation of authentication for only specified services, can only be enabled on a member of the Windows Server 2003 family.

The following steps are necessary if you want to use Kerberos in WSS/MOSS.

10. In SharePoint Central administrator site, In Application Management, Select Authentication Providers

11. In Authentication Provider select Window Membership Provider from default zone and Check IIS Authentication Settings.

a. Integrated Windows authentication check box should be selected

b. Select Negotiate (Kerberos) option

clip_image012

Figure 7 : SharePoint Central Admin – Edit Authentication

You should now be able to login to List Web Part and view the configuration page.

clip_image014

Figure 8 : Successful Login in List Web Part

Cheers,

Suraj Supekar

Advertisements

CRMUG – Creating CRM Communities

January 15, 2009 Leave a comment

Today our guest blogger is Mark Rhodes the program coordinator of CRMUG.com. In this example he communicates with the members in Northwestern USA. If you want to join or start a group in your part of the globe let Mark know.

AXUG Banner

CRMUG Pacific Northwest Regional Chapter

Please join us for the first meeting of the CRMUG Pacific Northwest Regional Chapter. This meeting is open to CRM users at all levels of experience: pre-implementation, currently implementing, seasoned veterans, as well as anyone considering Dynamics CRM as their customer relationship solution. The meeting will offer great networking, knowledge-sharing, and expertise through presentations and roundtable discussions.

About CRMUG Regional Chapters
Regional Chapters enhance your membership in CRMUG by offering face-to-face interaction and knowledge-sharing with other Microsoft Dynamics CRM users in your region. By having meetings centrally located within your region, users from all job roles and levels in your company can participate by only driving a short distance. All job roles are welcome:

  • Customer Service
  • Sales
  • Information Technology

Join us so you can optimize the functionality, flexibility, performance and return on investment offered by CRM-and get better results from your CRM implementation back home. Feel free to invite CRM colleagues and other users within the region.

For more information about CRMUG, visit www.crmug.com.

Event Information:

Date:

January 22, 2009

Time:

10:00am – 3:00pm

US Pacific Time

Location:

Microsoft
Civica Office Building
205 108th Ave. NE, Suite 400
Bellevue, WA 98004

Register Now

Tentative Agenda

10:00 a.m. – 11:00 a.m.
Introductions & Welcome (users introduce themselves including a brief description of their company and CRM use)

11:00 a.m. – 12:00 p.m.
Presentation by Tanim Ahmed, CRM Technology Specialist, Microsoft (topic TBD)

12:00 p.m. – 01:00 p.m.
Networking Lunch

01:00 p.m. – 02:30 p.m.
“Experts” Panel comprised of representatives from Microsoft, Ascentium, Altriva, Madrona Solutions, CRM On Target/Triventure, and TenDigits Software

02:30 p.m. – 03:00 p.m.
Wrap up, plan next meeting

All CRM users are welcome to attend, regardless of whether they have joined CRMUG. Members of the CRMUG Partner Program are also welcome to attend. Partners that are not yet members of CRMUG please bear in mind that the objective of Regional Chapters is to exchange knowledge and Dynamics CRM experience. Partner personnel should possess deep CRM expertise and refrain from sales activities.

Cheers,

Mark Rhodes

Implementing Approval Verification Processes

January 13, 2009 1 comment

Today we welcome Microsoft Dynamics CRM MVP Umar Khan who is a Microsoft CRM Consultant. You can read more from Umar on his blog at http://umarkhan.wordpress.com.

In business processes, there are sometimes scenarios in which certain steps require approval, authorization or verification from specific users to move forward. Microsoft Dynamics CRM 4 can be customized to implement such Role based or User dependent processes. One such example could be the requirement of authorization if opportunity is of more than 10K USD. I will be suggesting few options for implementing such a feature.

Note: This article assumes that reader is familiar with CRM Customizations, the CRM SDK and web services.

First step will be creating a new bit (or picklist) attribute in the entity and then adding it on the form. Bit field can either have true or false value but existing records will have null value in the new bit field. If approval field has false value then it means current record is not approved yet, else if it has true value then it means it is approved. Another option can be to use the existing status field for approval and unapproval by adding new values in picklist of status reason field. Simplest solution will be to depend upon the users themselves to control the updating of the approval field. All the users will have access to update the approval field but normal CRM users may not try to change the value of approval field and only Manager User change the value to approve or unapproved as per their decision.

But better solution will be to enforce the process and making sure that unauthorized user could not change the value of approval field. So by using web service call in “on load” event of the form, we can determine the current login user and then can make the approval field enabled or disabled depending upon the current login user’s rights.( How to Control Update Access for a Field )

There are some other options also available for implementing this process with more interactive interface;

a. Using JavaScript’s Confirm box:

1. After creating a field on entity to store the Approval or Unapproval status, add it on form and make it read only. By default its value will be false.

2. Add an “Approval” button on the toolbar of the entity window. A click on it will trigger the approval functionality.

3. When user clicks this button, using web service, check if the current login user is the authorized person to give the approval.

4. If it is not then alert the message that “You are not authorize to approve.”

5. If it is the authorized person then show “Confirm” box for user input.

  1. if ( confirm(“Please approve the credit facility for the Account.”) )
  2. { alert (“Approved”);}
  3. else
  4. { alert (“Unapproved”);}

clip_image002

6. If OK is pressed then make the approve status field to True otherwise its value will be False. Using JScript, you can enable or disable fields on the form depending upon the approval status.

Note: JavaScript’s “Prompt” box can be used if you want the user to also pass some important value before moving further.

clip_image004

JavaScript solution is suitable when requirement is for only approval and unapproval. If end user needs to perform more actions than most probably the second option will be better.

b. Model window ASPX web form:

ASPX web form can be used to give CRM user more options then only Ok and Cancel. Basically an ASPX page can be developed to be shown in model window for user input. A modal dialog box retains the input focus while open. The user cannot switch windows until the dialog box is closed. Opportunity Close window is an example of this form. This ASPX page development will involve good understanding of .net and CRM SDK and it will be hosted on Web Server. This model window may open on click of the “Approval” toolbar button. Steps will be almost same as JScript Prompt box. In case CRM Users are using Outlook offline client, then this ASPX page is required to be hosted in all the client machines also to make this feature functional in case of offline mode.

c. CRM Workflow:

CRM workflows are one of the mostly used solutions for the approval feature. Develop “on demand” workflow rule which is only accessible to authorized users. A complex authorization process can be easily implemented in CRM workflows. Workflows will mostly give solution without involving coding and they will be easy to manage and deploy. Workflows can also be triggered on the click of a toolbar button with the help of some JScript. The disadvantage in this solution is that it will take few seconds before workflow is executed and if form is still open then it will not automatically refresh to reflect the changes on the form. User needs to manually refresh the page to see the changes like change of value in approval field. Sometimes, changes are not required to be seen immediately; in those cases this solution is ideal.

clip_image006

If you have some specific scenarios with different solutions, we’d love to hear from you.

Cheers,

Umar Khan

Troubleshooting the Microsoft Dynamics CRM E-mail Router

January 12, 2009 Leave a comment

This post will give you some steps and links to additional information on troubleshooting the different errors you may seen when clicking Test Access to test the configuration of the e-mail router.

In order to troubleshoot the E-mail Router you will want to know what E-mail Access Configuration is set of your users. To find out the configuration you can view each user’s record in CRM under Settings-Application-Users. Each user can have a different configuration like the following.

clip_image002

clip_image004

For more information on the configuration options see the Email Router Scenarios Document.

Troubleshooting Incoming E-mail

If you have an error type HTTP 401 (Unauthorized)

clip_image006

Make sure the user has logged into the mailbox so the mailbox is activated before clicking “Test Access”. Also verify you can receive E-mails into that mailbox.

Check the properties of E-mail Router Incoming profile

  1. Verify the correct URL of the Exchange server is entered.

a. http(s)://myexchangeserver

b. http(s)://www.myexchangeserver.local

  •  
    • You should not put anything at the end like “/OWA” or “/Exchange” or even a simple “/”.

    2. Check the Access Credentials to see what they are set to(LocalSystem, UserSpecified, OtherSpecified).
clip_image008

Make sure that the user that is set in the Access Credentials has Full rights to access to the mailboxes you are testing access for. To test this, try to logon to the Router machine with the account set in the Incoming profile (Or do a run as in IE), then try to access to the OWA URL of the User you are currently testing (http://exchangeserver/Exchange/crmuser)

You can check these links below to give Mailbox rights to the user that is set in the Access Credentials of the Incoming Profile. For setting permissions on a mailbox in Exchange 2003 http://technet.microsoft.com/en-us/library/aa998707(EXCHG.65).aspx

For setting permissions on a mailbox in Exchange 2007, http://technet.microsoft.com/en-us/library/bb124097(EXCHG.80).aspx
http://mostlyexchange.blogspot.com/2007/02/granting-permissions-to-mailboxes-in.html

3. If User Specified is used in the access Credentials then make sure the user that you are trying to connect to has set their username and password in Tools-Options as the router will use those credentials to access the users mailbox.
Note: The User Specified option is used in the scenario where the router is monitoring user mailboxes. This would be when the users E-mail configuration is set to E-mail Router for the Incoming Profile.clip_image010

If you have an error type HTTP 400 (Bad Request), HTTP 404 (Not Found), HTTP 502 Bad Gateway, or The Remote name could not be resolved:

clip_image012

clip_image014

Make sure the Exchange URL you entered in the E-mail Router Incoming profile is correct, the syntax must be:

1. http(s)://myexchangeserver

2. http(s)://www.myexchangeserver.local

    a. You should not put anything at the end like “/OWA” or “/Exchange” or even a simple “/”.

Check IIS Logs on Exchange Server to see what Virtual Directory it is failing on (ExAdmin or Exchange)

1. IIS 6 – %SystemDrive%\WINDOWS\system32\LogFiles

2. IIS 7 – %SystemDrive%\inetpub\logs\LogFiles

Is SSL required on the Exadmin or Exchange virtual directory?

  • If so make sure to include https in the Exchange url when setting up the Incoming Profile.

Check if there is a Valid Certificate.

1. Do not use selfssl generated certificates

2. Try to navigate to the url that is set in incoming profile in IE

     a. http://servername/exchange/usermailbox

     b. Are there any Certificate Errors?

Check if Exchange 2007 roles are separated

  • If the Exchange Server roles are on separate machines make sure to use the Exchange server that is the mailbox server role when creating the incoming profile.

If you have an error type HTTP 404 (Not Found)

clip_image016

For Exchange 2007

Connect to the Exchange server (Mailbox Server) and in IIS Console Management, verify that the Virtual Directory we are using to connect to the mailboxes are present ( “Exadmin” or “Exchange”).
To do this, expand the default website in INETMGR, and check that EXADMIN folder is there.
If not, this is probably your problem; you will need to re-create it. The following KB Article gives a method to recreate the AD objects / IIS Metabase missing entries.
http://support.microsoft.com/kb/947802 You cannot connect to a clustered Exchange 2007 server through a server that has the Client Access Server (CAS) role installed by using the /exchange virtual directory

The issue could be the CRM User’s E-mail address information. The E-mail Address needs to be verified in CRM (check there is not mistyped address for instance).

For Exchange 2003

We need to make sure that the E-mail Address Login information is the same as the user’s Domain Name login.

Ex: User1 has the following properties set in CRM User Form:
DomainName: DOMAIN\user1
E-mailAddress: user1@domain.com

=> This works!

User2 has the following properties:
DomainName: DOMAIN\user2
E-mailAddress: CRM.User@domain.com
=> This will fail!

For the moment, we have a workaround for customers experiencing this. Here is how to do it based on the example above.

NOTE: If you are using Exchange 2007 you shouldn’t face this problem.

1. Make sure CRM User’s properties are set to use the E-mail Address they want (CRM.User@domain.com)

2. Configure the E-mail Router using the Configuration Manager, publish the changes.

3. Stop the E-mail Router Service. Open Microsoft.Tools.Crm.EmailAgent.Xml file in an editor like notepad.

4. On top of the file, set ConfigUpdatePeriod = 0

5. Modify each CRM User’s incoming profile like this:

<ProviderConfiguration deploymentId=”071e0a6e-649a-44da-a658-79dbffccfbe8″> <ProviderAssembly>Microsoft.Crm.Tools.EmailProviders.dll</ProviderAssembly>
<ProviderClass>Microsoft.Crm.Tools.Email.Providers.ExchngePollingMailboxProvider</ProviderClass><CrmServerUrl>http://crmserver:5555/MSCRMOrg</CrmServerUrl&gt; <CrmAuthMode>WindowsAuthentication</CrmAuthMode>
<EmailServer>https://mail.ex.com</EmailServer&gt;
<EmailAuthMode>WindowsAuthentication</EmailAuthMode>
<EmailUser>DOMAIN\User2</EmailUser>
<EmailPassword>{2A48C4DB-F2BFZ3g==@MkoEoFd1wvV8bY8UijX7VA==</EmailPassword> <EmailAddress>CRM.User@domain.com</EmailAddress>
<Target>User2</Target>
<Direction>Inbound</Direction>
etc…..
Change ONLY the SUFFIX: CRM.User into User2 like this: <EmailAddress>User2@domain.com<EmailAddress>

6. Save the file and restart the E-mail Router service.

NOTE: No need to perform the TEST ACCESS it will not work! If you want to check if the Router is working, monitor the trace and errors and do real tests. The test access will pick up the information from the CRM Server directly and not from the File, thus the “Fix” will not be used.

If test access does work, but you are receiving 404 errors in the application event log when processing E-Mail messages.

There is a known issue if Exchange 2007 is on Windows 2008 (IIS7). If you check the IIS logs for this 404 Error you will find that the exact status is:

    Request Filtering: Denied because URL doubled escaping 404.11

To address this you need to allow double escaping on the Exchange website by running this command:

%windir%\system32\inetsrv\appcmd set config “Default Web Site” -section:system.webServer/security/requestfiltering -allowDoubleEscaping:true

Find more information here:
http://technet.microsoft.com/en-us/library/cc754791.aspx
http://learn.iis.net/page.aspx/143/how-to-use-request-filtering/

If you have an error type HTTP 440 (Login Timeout)

  • This usually is due to not using Windows Authentication (only supported authentication method) but Forms Based Authentication. You need to change the authentication mode to Windows Authentication on the Mailbox Server . http://support.microsoft.com/kb/954047 ,
  • Make sure to point the Incoming Profile to the Exchange server with the mailbox server is and where the ExAdmin and Exchange virtual directories are.

You can also check this: http://blog.networkfoo.org/?p=195

Troubleshooting Outgoing E-mail

“Outgoing status: Failure – An error occurred while checking the connection to e-mail server EXSERVERNAME. The requested address is not valid in its context”

If the Outgoing Test is failing during Test Access:

  • Perform a simple telnet command to verify that connectivity between CRM Router and Exchange is fine.
    Ex: TELNET EXSERVERNAME PORT
  • Ensure you don’t have any Antivirus services running on the machine preventing calls on port 25.
  • See http://support.microsoft.com/kb/915827 for steps on configuring SMTP server to allow relay messages from Microsoft Dynamics CRM.

Troubleshooting Loading Data

When Clicking on Load Data you receive the following error.

The E-mail Router Configuration Manager was unable to retrieve user and queue information from the Microsoft Dynamics CRM server. This may indicate that the Microsoft Dynamics CRM server is busy. Verify that URL ‘http://hansoncrm5:5555/MSCRm&#8217; is correct. Additionally, this problem can occur if specified access credentials are insufficient. To try again, click Load Data. (The organization name in the URL is case-sensitive. You must type the organization name in the URL exactly as it appears in the Microsoft Dynamics CRM server. To view the organization name as it appears in the Microsoft Dynamics CRM server, start the Web application. The organization name is displayed in the upper-right corner of the application.)

  • Make sure the account that is running the Microsoft CRM 4.0 E-mail Router Service is added to the PrivUserGroup Security Group in Active Directory.
  • The Account that is specified for the Access Credentials needs to be a CRM Admin User. If the Access Credentials are set to Local System then the computer Account needs to be a member of the PrivUserGroup Security Group in Active Directory.
  • Make sure the url is spelled correctly as it is case sensitive for the Organization Name.
  • DeploymentProperties table may have incorrect values if you have modified the port or hostheaders on your website. To update the DeploymentProperties table see http://support.microsoft.com/kb/950248

Additional Information

If unable to start the Microsoft CRM Email Router service start here http://support.microsoft.com/kb/954522

Incoming Status: Failure – The E-mail Router service configuration parameter “Emailuser” is missing. This parameter is required. http://support.microsoft.com/kb/947094

Email Router Scenarios Doc http://www.microsoft.com/downloads/info.aspx?na=22&p=1&SrcDisplayLang=en&SrcCategoryId=&SrcFamilyId=&u=%2fdownloads%2fdetails.aspx%3fFamilyID%3d8ea05b4e-825a-4db1-ad59-d894aa5ef33e%26DisplayLang%3den

Blog on how to enable tracing
http://blogs.msdn.com/benlec/archive/2008/03/25/how-to-implement-logging-for-the-microsoft-crm-4-0-e-mail-connector.aspx

Blog on E-Mail Connector Tracing tool
http://blogs.msdn.com/benlec/archive/2008/07/02/crm-4-0-e-mail-connector-logger-tool.aspx

Blog for troubleshooting
http://blogs.msdn.com/benlec/archive/2008/05/05/troubleshooting-crm-e-mail-issues-in-microsoft-crm-4-0.aspx

Info on virtual directories used for exchange
http://technet.microsoft.com/en-us/library/aa998849(EXCHG.80).aspx

Hotfixes
http://support.microsoft.com/kb/954549 (In Update Rollup 1)
http://support.microsoft.com/kb/952019 (In Update Rollup 1)
http://support.microsoft.com/kb/951849 (In Update Rollup 1)
http://support.microsoft.com/kb/959248 (Coming In Update Rollup 2)

Kind Regards,
The Microsoft CRM Support Team

Building Rich-Client Dashboards for Microsoft Dynamics CRM with Windows Presentation Foundation

January 12, 2009 1 comment

This month I am pleased to introduce Jeremy Hofmann, a Manager in Crowe Horwath’s Dynamics CRM practice and is responsible for many successful deployments of Dynamics CRM across North America. In his usual style Jeremy steps out of the box and shows how Microsoft Windows Presentation Foundation can be leveraged in Microsoft Dynamics CRM 4.0.

Microsoft CRM 4.0 allows your organization to track accounts, contacts, leads, opportunities, activities, support cases, and a vast array of additional business information users need. In addition, you can leverage the platform to create your own related custom entities that model your business information and allow your users to manage day to day customer interactions.

From a user’s perspective, the power and flexibility to extend the system is incredible, but it has the potential to cause usability issues. How do busy users quickly and easily get access to the most relevant information? How can you provide a targeted, personalized user experience that presents CRM information and relationships directly to the user in time of need?

The answer is to customize the user experience by bringing together the most frequently used, and most relevant data all in one central location – to build a CRM “dashboard”. This is where the challenge presents itself – defining the information to be displayed, and determining how to build a fast and responsive solution to provide the best user experience possible.

In this article, I’ll show you how to build your own custom CRM dashboards, using Microsoft’s Windows Presentation Foundation to construct the user interface.

What You Will Need

You can design Windows Presentation Foundation (WPF) applications using Microsoft Visual Studio 2005 or 2008. I prefer to use VS 2008 since it’s the latest and greatest. Feel free to use the Visual Studio 2008 Express edition, as it is free to download and easy to install.

If you use Visual Studio 2005, you will need to download and install the Visual Studio 2005 Extensions for .NET 3.0.


The Dashboard

Here’s a sample dashboard we’ll build together. This dashboard lists CRM accounts on the left side. When an account is selected on the left, the dashboard will display the related record information on the right. You can add, remove, or customize the panels as you see fit for your users. In a moment, you’ll see how easy it is to bind CRM data to a WPF template in order to display this information.

Hoff01

Getting Started

Let’s get started by creating a new Windows Presentation Foundation project in Visual Studio. Select the “WPF Application” template and give your project a name.

Hoff02

Visual Studio will load the template and present you with a brand new Window1.xaml file for you to work with. Add a web reference to the CRM web server. I called mine CRMService. If you need additional information on this topic, there is more information in the CRM 4.0 SDK on how to do this.

Hint: If you are using Visual Studio 2008, you may have a little trouble finding the “Add Web Reference” option. It’s still there – first use the “Add Service Reference” menu, and then click the Advanced button.

We’ll also need to reference the Microsoft CRM SDK .dlls, microsoft.crm.sdk.dll, and microsoft.crm.sdktypeproxy.dll, which can be found in the bin folder of the Microsoft CRM SDK. Go ahead and set a reference to those assemblies as well.

Actually, we’ll be referencing the CRM web service and the SDK assemblies quite a bit, so let’s set up a using statement to make things a little cleaner. Now we’re ready to go!

using CRM.Dashboard.CRMService;

The Account List

The first thing we’ll do is create the account list on the left side. This will allow the user to select an account. In this section, we’ll connect to the CRM web server, query all accounts, and then create the WPF markup to display the accounts. Finally, we’ll show how to bind the accounts to the WPF control.

View the code behind the Window1.xaml, add a class level variable to reference the CRMService, and modify the default Window1 constructor to create a new instance of to the CRM service.

   1: public partial class Window1 : Window
   2: {
   3:    // reference to the CRM web service
   4:    CrmService crmService = null;
   5: 
   6:    ...
   7: }
   8: 
   9: public Window1()
  10: {
  11:    // default code – leave this here
  12:    InitializeComponent();
  13: 
  14:    // create an authentication token
  15:    CrmAuthenticationToken token = new CrmAuthenticationToken();
  16:    token.AuthenticationType = 0;
  17:    token.OrganizationName = "MicrosoftCRM";
  18:
  19:    // set up the CRM web service
  20:    crmService = new CrmService();
  21:    crmService.Url = "http://crm/mscrmservices/2007/crmservice.asmx";
  22:    crmService.CrmAuthenticationTokenValue = token;
  23:    crmService.Credentials =
  24:     System.Net.CredentialCache.DefaultCredentials;

You may have to change the CRM service URL to point to your CRM server. If you’re using the Microsoft Virtual PC image, change it to http://localhost:5555/&#8230;.

So far this is just standard CRM development. We’ve added a web reference to our CRM web service and we’ve created an instance of the class.

Now we need to connect to the CRM web service and retrieve the CRM accounts. We’ll retrieve the accounts as BusinessEntity objects so that we can bind to them using WPF. In the Window1 constructor, add the following code after the code to connect to the CRM web service.

   1: // Create the QueryExpression object.
   2: QueryExpression query = new QueryExpression();
   3: query.EntityName = EntityName.account.ToString();
   4: query.ColumnSet = new AllColumns();
   5: 
   6: // Retrieve the contacts.
   7: BusinessEntityCollection accounts = crmService.RetrieveMultiple(query);

Great! This by itself should compile and run. However, it does not yet do anything too spectacular. Next is the fun part – creating your own XAML markup to render the account list any way you’d like.

WPF Designer

Switch over to the Window1.xaml designer. You should see the following design pane:

Hoff03

Notice here there are two main design panes. The top pane is a graphical preview of the changes you make in the markup section in the bottom pane. You can collapse either pane if you prefer to work in one or the other. I prefer to work in the text (bottom) pane since I like to torture myself…I mean, have total control…over the markup design. It’s also a great way to learn WPF markup if you are just getting started with it.

Notice also that there is a top-level Window element and a single Grid element within it. I won’t go into all the details here of the Window element, just know that it is the default element when creating WPF applications and that you can change some of the basics within it, such as the title bar text, height, and width of the window.


WPF Layout

Now some background – WPF is a little like HTML. The idea is for you to markup the layout and presentation for what you’d like to show and the system will render this markup for you when the program runs. It’s also a bit like HTML in that you can put elements and controls inside of one another, and “build up” your user interface as a sort of tree.

One of the main elements in WPF is the Grid. You can think of a Grid almost like a table, with rows and columns. Within the Grid, you can pin down controls so that they are rendered at an exact row and column.

In our dashboard, we’ll want to have two main columns. The first column will contain our accounts list, and the second column will contain all of our panels and related information.

Within the Grid element, place the following markup.

   1: <Grid Name="grdMain" Background="DimGray">
   2:         <Grid.ColumnDefinitions>
   3:             <ColumnDefinition Width="40*"></ColumnDefinition>
   4:             <ColumnDefinition Width="60*"></ColumnDefinition>
   5:         </Grid.ColumnDefinitions>
   6: </Grid>

The Width values tell WPF how wide to make each column. As a best practice, I like to make all of my column widths add up to 100. This allows you to treat each column width as a percentage, similar to HTML table design. In this example, the first column will take up 40% of the width, and the second column will take up the remaining 60%.

Another common layout element in WPF is the DockPanel. A DockPanel allows you to put other controls inside of it, and to “dock”, or fix, each control to either the top, bottom, left, or right side of the DockPanel. This allows for great flexibility and automatic stretching and resizing of the child controls.

Let’s throw down a new DockPanel in the first column of the Grid. Place the following markup in the Grid element, after the Grid.ColumnDefinitions element.

<DockPanel Grid.Column=”0″>

</DockPanel>

Back to the Accounts List

Now we can add our list view to display the list of accounts. Add the following markup within the DockPanel that we just created.

   1: <DockPanel>
   2: 
   3:    <DockPanel DockPanel.Dock="Top">
   4:     <TextBlock DockPanel.Dock="Left" Text="Accounts"
   5:         Foreground="White" FontWeight="Bold"
   6:         FontSize="14">
   7:     </TextBlock>
   8:    </DockPanel>
   9: 
  10:    <ListView Name="lstMain" Foreground="Orange" Background="DimGray">
  11:     <ListView.View>
  12:            <GridView AllowsColumnReorder="true">
  13:            <GridViewColumn
  14:               DisplayMemberBinding="{Binding Path=name}"
  15:             Header="Name"/>
  16:        </GridView>
  17:     </ListView.View>
  18:    </ListView>
  19: 
  20: </DockPanel>

Some things to point out here – first, there’s another DockPanel with a TextBlock inside. This is just a section header label we’ll use so the user can identify the section.

Second, we’re using the ListView control. This is just a WPF control that works very similar to a .NET data grid. You define one or more columns and then bind those columns to a field in your data.

In this example, we are defining a GridViewColumn element within the GridView, and then we are setting the DisplayMemberBinding attribute to the “name” property from our data. This is all it takes to tell WPF which field from the CRM record you want to display in that column! Feel free to add additional columns from the CRM account record if you’d like.

Finally, we need to tell this ListView where to get its data from. Back in the code view, add a line of code immediately after retrieving the CRM accounts from the CRM web service.

// Bind the accounts to the WPF list view

lstMain.ItemsSource = accounts.BusinessEntities;

Now if you compile and run, your CRM accounts list should be populating with a list of accounts from your CRM system. Fantastic!

Hoff04

Related Panels

What kind of dashboard would we have if we didn’t display related information? In the following sections, we’ll add some additional panels to display the general information from the account, associated activities, and even mix in a CRM web page just for fun.

General Information Panel

In this panel, we’ll display a few of the account record details. Begin by adding the following markup to the designer, immediately after the first DockPanel that we added above.

   1: <DockPanel Name="panMain" Grid.Column="1" LastChildFill="True">
   2:    <StackPanel DockPanel.Dock="Top">
   3:        <StackPanel>
   4:          <TextBlock Text="General Information" Foreground="White"                 FontWeight="Bold" FontSize="14"></TextBlock>
   5:          <TextBlock Text="{Binding Path=name}"
   6:              Foreground="Orange"></TextBlock>
   7:        <TextBlock Text="{Binding Path=address1_city}"                         Foreground="Orange"></TextBlock>
   8:        <TextBlock Text="{Binding Path=address1_state}"
   9:             Foreground="Orange"></TextBlock>
  10:        <Canvas Height="20"></Canvas>
  11:       </StackPanel>
  12:    </StackPanel>
  13: </DockPanel>

This is just another DockPanel. This time we threw a StackPanel inside of it, placed a StackPanel inside of that, then added four TextBlock controls inside of that. The first StackPanel just anchors the following controls to the top of the DockPanel. The second StackPanel then tells WPF to render the following controls in order, top to bottom. The first TextBlock just displays some fixed text for the section header. Each TextBlock after that is bound to a specific field on the account record.

Don’t worry too much about the binding syntax for now – it looks a little funny at first but there are plenty of samples out there for you to reference. The key is to set the Path property to the attribute that you want to display.

The real magic comes when we bind the DockPanel to the account record. To do this, first we need to add an event handler to the account list, telling it to run some code whenever anyone clicks an account. Add a MouseUp property to the lstMain ListView control that we created earlier.

<ListView Name=”lstMain” MouseUp=”GridViewColumn_MouseUp” …>

Now switch back to the code and add the following event handler code.

   1: private void GridViewColumn_MouseUp(object sender,
   2:     MouseButtonEventArgs e)
   3: {
   4:     ListView c = (ListView)sender;
   5:     account a = (account)c.SelectedItem;
   6:       panMain.DataContext = a;
   7: }

Now whenever someone clicks an account in the account list, the program will pull the account out of the list and bind the DockPanel to that account. It’s that easy.

Run the program again and select an account to make sure you’re on the right track.

Hoff05

Activities Panel

In the next panel, we’ll display a list of the open and closed activities for the account. Add the following markup to the designer, immediately under the last StackPanel that we added for the “General Information” section, and within the DockPanel.

   1: <StackPanel DockPanel.Dock="Top">
   2: <StackPanel>
   3:     <TextBlock Text="Activities" Foreground="White" FontWeight="Bold"
   4:         FontSize="14">
   5:       </TextBlock>
   6:     <ListView Name="lstActivity" Background="DimGray"
   7:         Foreground="Orange">
   8:         <ListView.View>
   9:             <GridView>
  10:                 <GridViewColumn DisplayMemberBinding="{Binding  Header="Subject"/>
  11:                     Path=subject}"
  12:                 <GridViewColumn DisplayMemberBinding="{Binding 
  13:                     Path=scheduledend.date}"
  14:                     Header="Due Date"/>
  15:             </GridView>
  16:         </ListView.View>
  17:     </ListView>
  18:     <Canvas Height="20"></Canvas>
  19: </StackPanel>
  20: </StackPanel>

This is just like the ListView that we added to display the accounts. The only difference here is that we are displaying fields from the activity entity.

Back in the code behind, we’ll need to grab the activities for the selected account and bind the results to the ListView. Place this code in the GridViewColumn_MouseUp handler, immediately after the existing code.

   1: // Create the query object
   2: QueryByAttribute query = new QueryByAttribute();
   3: query.ColumnSet = new AllColumns();
   4: query.EntityName = EntityName.activitypointer.ToString();
   5: 
   6: // This query will retrieve all activities for the account
   7: query.Attributes = new string[] { "regardingobjectid" };
   8: query.Values = new string[] { a.accountid.Value.ToString() };
   9: 
  10: // Execute the retrieval
  11: BusinessEntityCollection retrieved =
  12:     crmService.RetrieveMultiple(query);
  13: 
  14: // Bind the activities to the list view
  15: lstActivity.ItemsSource = retrieved.BusinessEntities;

Run the program again to make sure everything is coded properly. You now have a working WPF dashboard!

Hoff06

Embedding a Web Page

The final dashboard component we’ll add is an embedded web page to display the CRM activity. When the user clicks the activity in the activity list, the panel will display the actual CRM activity web page directly in the WPF application.

First, let’s add the event handler markup for the MouseUp event to the lstActivity ListView.

<ListView Name=”lstActivity” MouseUp=”lstActivity_MouseUp” … >

Now add the markup to display the web page, immediately after the last StackPanel but still within the main DockPanel.

   1: <DockPanel>
   2:     <DockPanel>
   3:         <TextBlock DockPanel.Dock="Top" Text="Record Details"
   4:             Foreground="White" FontWeight="Bold"
   5:             FontSize="14"></TextBlock>
   6:         <Frame Name="frmCRM"
   7:             ScrollViewer.CanContentScroll="True"></Frame>
   8:     </DockPanel>
   9: </DockPanel>

This works a bit like a CRM iFrame control. Our job is to set the Frame’s source property in the click event. Add the following in the code behind.

private void lstActivity_MouseUp(object sender, MouseButtonEventArgs e)

   1: private void lstActivity_MouseUp(object sender, MouseButtonEventArgs e)
   2:         {
   3:             ListView c = (ListView)sender;
   4:             activitypointer a = (activitypointer)c.SelectedItem;
   5:             string activityId = a.activityid.Value.ToString();
   6:             this.frmCRM.Source = new
   7:             Uri("http://crm/activities/task/edit.aspx?id={"
   8:                 + activityId + "}");
   9:         }

Now when a user clicks the activity, the Frame will switch to the CRM web page for that activity.

Give it a try.

Hoff07

Decorating the Panels

A WPF application wouldn’t be a WPF application unless you spiced up the style a bit. I this section, I’ll show you some tricks you can use to give the dashboard a little pizzazz.

Let’s add a rounded border to our panels. WPF makes this very easy if you use a Border element. You can decorate your DockPanels and StackPanels with a Border element, and set the CornerRadius and Margin properties so that they will render with a rounded table effect.

Add the following markup just inside the first DockPanel.

   1: <DockPanel Grid.Column="0">
   2:     <Border BorderBrush="White" BorderThickness="1"
   3:         CornerRadius="5" Margin="5">
   4:
   5:         ...
   6: 
   7:     </Border>
   8: </DockPanel>

Notice the results. You can control the “roundness” of the border by adjusting the CornerRadius property. Also, play around with the BorderThickness property to increase or decrease the border’s width.

Hoff08

Repeat the Border markup inside of the General Information, Activities List, and Activity Frame panels. For the General Information and Activities list, you will want to place the border directly inside of the StackPanel element. For the Activity Frame, place it directly inside of the first DockPanel.

   1: <DockPanel Name="panMain" Grid.Column="1" LastChildFill="True">
   2:     <StackPanel DockPanel.Dock="Top">
   3:         <Border BorderBrush="White" BorderThickness="1"
   4:             CornerRadius="5" Margin="5">
   5:             ...
   6:         </Border>
   7:     </StackPanel>
   8: 
   9:     <StackPanel DockPanel.Dock="Top">
  10:         <Border BorderBrush="White" BorderThickness="1"
  11:             CornerRadius="5" Margin="5">
  12:             ...
  13:         </Border>
  14:     </StackPanel>
  15: 
  16:     <DockPanel>
  17:         <Border BorderBrush="White" BorderThickness="1"
  18:             CornerRadius="5" Margin="5">
  19:             ...
  20:         </Border>
  21:     </DockPanel>
  22: </DockPanel>

Hoff09

Finally, we’ll set the title property, startup size, and start up location of the Window element at the very top of the markup designer.

   1: <Window x:Class="CRM.Dashboard.Window1"
   2:         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3:         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4:         Title="CRM Dashboard" Height="400" Width="600"
   5:     WindowState="Maximized" WindowStartupLocation="CenterScreen">

Next Steps

By now you’ve seen how to create a basic WPF application, how to add markup to display CRM information, and how to connect your application to your CRM data.

You could take this application and add additional panels, display geographic or map information, embed SQL Reporting Service reports, SharePoint parts, or any other data that your users would find relevant.

You could also extend the dashboard to allow your users to import and arrange custom panels that you publish to a central location. The sky’s the limit.

Conclusion

We’ve seen how CRM 4.0 can be combined with WPF to give your users a rich client experience, with relevant CRM information at their fingertips. All of this takes place inside of a rich client-side application that will provide your users with a speedy, interactive application that can be enhanced over time.

I encourage you to try building a dashboard of your own, and to learn more about the display capabilities of Windows Presentation Foundation. I think you’ll find it provides a powerful new interface for building rich client applications that will make your users more productive, well-organized, and happy.

Cheers,

Jeremy Hofmann

Jeremy is a Manager within Crowe Horwath’s CRM practice and specializes in combining Microsoft CRM with related technologies. He lives in the Chicago area and can be contacted at jeremy.hofmann@crowehorwath.com.

The First ‘ Microsoft Dynamics CRM Incubation Week’

January 12, 2009 Leave a comment

Wow!! What an incredible experience of hosting our first ever Microsoft Dynamics CRM Incubation week. I would say two key aspects (communal and entrepreneur) made this event a huge success.

Five Startups (out of 50+) were invited for a week at MTC Reston to learn, and develop their business idea using Microsoft Dynamics CRM as a Rapid Development/Deployment Platform. Each startup team along with their assigned advisor (Thanks Jim Steger and Dan Blake for investing your time and money) and an offshore development company (Thanks Nilesh Patel from Proteans), worked very long hours every day to develop working prototypes.

In addition to technology, we had several business/industry guest speakers to cover topics like ‘How to market your solution’, ‘How to raise money’, and ‘How to build a S+S business’. On Friday, each team pitched their business plan with solution demo to a panel of judges (VCs, CRM Thought Leader, Incubator), and could walk away with their own IP (in some cases near production ready code).

The event got very good blog/PR coverage including from Paul Greenberg, well known CRM thought leader; Joe Zuccaro, neutral blogger; Jeremy Epstein, marketing expert. These blogs highlighted Microsoft’s commitment to work with startups in today’s tough economy and our investment in the BizSpark initiative.

The following awards were won by the indicated companies.

Award Category

Startup Team

Best Business Award (1st)

Highland Martin,  LLC

Best Business Award (2nd)

DubMeNow

Super Cool Award (1st)

support4U Inc.

Super Cool Award (2nd)

Channel Blade Technologies

Advisor Award

Prime Time Software Solutions LLC

You can see the detailed event coverage at Sanjay Jain’s various blog posts (Day0, Day1, Day2, Day3, Day4, Day5). Feel free to send your questions/comments to Sanjay JainYou can submit your nomination for future CRM Incubation Weeks by following the directions at Sanjay Jain’s blog.

Thanks,
Sanjay Jain

What are Your New Years Resolutions?

January 9, 2009 Leave a comment

Every time I say 2009, I have been pausing. It sounds almost like it is in the future and yet, here it is a new year. Not all of us do the New Year Resolution thang. But I have been thinking about it a lot because this year promises to be in some ways very scary and in other ways moving to better times.

I came across this CRMHelpDeskSoftware.com article and I thought I’d share it with you. This excellent piece is Call Center centric but could be for many different kinds of CRM applications. I especially liked recommendation number two:

Automate to Alleviate – Call centres are challenged with striking a balance between three competing priorities: customer satisfaction, reducing cost and revenue. Focusing too much on increasing customer satisfaction could drive up call times and increase costs. Focusing on cost containment could negatively impact customer satisfaction. Focus too much on revenue generation and customer satisfaction could suffer. To achieve a balance organisations need to find the right combination of automated and agent assisted interactions.

The majority of customer calls are simple and task-based that can be effectively automated to alleviate pressure on agents and reduce costs. Using speech recognition to automate just 10% of transactions such as bill payments, balance transfers or account enquiries, a call centre taking 5m calls per year could save approximately £800,000 annually.

Read more…

I have always been the kind of guy to automate my work as much as possible as I’ve progressed through my career. I started by automating my weekly reports when I was a 2LT in the military in the early 80s. I was the only officer I knew in Germany who owned his own computer. And the hours spent hand typing out our weekly reports was for me replaced by time with my soldiers and on job sites.

So what are your resolutions for the new year? Will you be automating some of your workload? Or maybe you pursue more education through Microsoft Dynamics CRM certification. We’d love to hear back from you.

Cheers,

JaAG