Wednesday, September 30, 2009

Issues after Re-Naming MS CRM Servers computer/machine name

Currently I faced a scenario where the machine on which MS CRM 4.0 was installed was required to be renamed on LAN. My deployment had the SQL Server installed on another machine on LAN.

After changing the MSCRM Server machine name, MS CRM browser stopped working and started showing error “SqlException: Login failed for user [Domain Name]\[New Machine Name].” This error comes when the MS CRM server related entries in registry and database (that refer to the server name) have not yet been changed to the new server name

This problem could be solved by 'Repairing’ the MS CRM 4.0 installation on the machine after renaming it.
Go to the Control Panel -> Add or Remove programs-> Microsoft Dynamics CRM Server. Repair the installation.

Repair installation internally performs the following actions:
a. In the registry, ServerURL key value at HKEY_LOCAL_MACHINE/SOFTWARE/MICROSOFT/MSCRM is updated with the new machine name (example: the value would be like “http://:5555/MSCRMServices”).
b. Adds new server name entry to dbo.server table in the MSCRM_CONFIG database.
c. Adds the new machine name (computer name) to the PrivUserGroup and SQLAccessGroup in the active directory groups.

These steps could also be performed manually (I actually performed steps a) and c) manually before ‘Repairing’  ).

These steps should ensure correct working of MS CRM in case of renaming of server machine after installing MS CRM 4.0.

Tuesday, September 22, 2009

Working with MSCRM 4.0 Reports in IFD deployment

Recently for a project requirement I had to deploy MSCRM 4.0 on an IFD server. Everything else seems to work properly except the Reports. The reports were running good on on-premise configurations for the same organization. This issue was same for Custom reports as well as the out-of-box reports by MS CRM.

Its then I read that this is a common issue with IFD deployment. To resolve this, the deployment must be running the Microsoft Dynamics CRM Connector for Microsoft SQL Server Reporting Services.

The SRSDataConnector for MS CRM 4.0 comes with the installation files for MS CRM 4.0 and is located on the installation CD: “drive:\Server\i386 \srsDataConnector” folder. Run the “setupsrsdataconnector.exe” executable in the mentioned folder and you are done with it!

How does it work? - When a Microsoft Dynamics CRM report is run, Microsoft SQL Server Reporting Services Viewer requests the report and data from the remote Microsoft SQL Server Reporting Services computer. To access the report, the Microsoft Dynamics CRM server URL is used. Microsoft Dynamics CRM Connector for Microsoft SQL Server Reporting Services runs as a Microsoft SQL Server Reporting Services data processing extension and handles the authentication in the delegated mode used for reports.

However, there is a limitation with the connector too. The MS CRM connector doesn't work with the Microsoft SQL Server 2005 Workgroup Edition. This is because the Workgroup edition does not support custom data extensions used in the Microsoft Dynamics CRM Connector for Microsoft SQL Server Reporting Services. So, to further resolve this, one should use Standard Edition OR Enterprise Edition of SQL Server. This is applicable for both SQL Server 2005 OR SQL Server 2008 Installations.

Tuesday, September 15, 2009

Initializing distinct XAMLs included in a single XAP

So I had a situation where I had to load multiple charts on my custom page default.aspx within Microsoft Dynamics CRM. These charts rendered different reporting data after fetching it using the MS CRM webservices.
I used silverlight visifire charts for each of my reports. Instead of creating a different silverlight application for each of my reports, I instead created different XAMLs for each of them and compiled a single XAP. Well, this is a well tried and tested approach used in any silverlight application or any aspx application using Silverlight controls which involves multiple XAMLs compiled in a single XAP. These are the steps I used:

1. Created a Silverlight application that contained multiple XAMLs each one including a different report (i.e. a different visifire chart) and compiled it as one "SLDashboardPOC.xap".

2. For each of the reports to be rendered, I embedded the compiled Silverlight XAP control multiple times in my default.aspx as follows:

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div>
<asp:Silverlight ID="Xaml1" runat="server" Source="~/SL/SLDashboardPOC.xap"
MinimumVersion="2.0.31005.0" Width="66%" Height="50%" />



<asp:Silverlight ID="Xaml2" runat="server" Source="~/SL/SLDashboardPOC.xap"
MinimumVersion="2.0.31005.0" Width="66%" Height="80%" />
.
.
.
and so on..

Now, at the time of rendering the reports I had to specify to my embedded XAP(s) which XAML page to initialize and render. I fetched datasets for different reports using the MS CRM web services from my business tier and converted them into XMLs using dsReportData.GetXml().ToString(). Then I passed these distinct dataset XMLs as parameters to the different visifire charts included in my XAP. I did this on my Page_Load by sending the datasets to my silverlight app as follows:

String strData1 = GetDataForReport1(); //This will return the dataset XML from MS CRM
initParams = "ReportParam1=" + strData1; //Create "Key=Value" Initialization parameters
Xaml1.InitParameters = initParams; //Add these to the collection of initparameters for the specific report

String strData2 = GetDataForReport2();
Xaml2.InitParameters = "ReportParam2=" + strData2;

4. Then I used these parameters in my Silverlight application's Application_Startup event to add them to the application's resources as follows:

if (e.InitParams.Count > 0)
{
foreach(var item in e.InitParams)
{
this.Resources.Add(item.Key , item.Value ); //Add each of the "Key=Value" pairs paased from the hosting page
}
}

if (e.InitParams.ContainsKey("ReportParam1"))
{
this.RootVisual = new Report1(); //This will define which XAML will be the default for the XAP. I specify a different RootVisual property for rendering each of the charts
}
if (e.InitParams.ContainsKey("ReportParam2"))
{
this.RootVisual = new Report2();
}

5. And finally while initializing my chart and rendering data, I used the applications' resources to fetch the report parameter that contained the dataset XML my chart required:
if (App.Current.Resources.Contains("ReportParam1"))
{
//Add data points to the chart and render it
{
}

Wednesday, September 9, 2009

Windows Prompt for an IFD Deployment

This blog will explain why Microsoft Dynamics CRM prompts for Windows Credentials when you log on to your development environment (configured for IFD ) using the server's IP address or the Host file configured URL (such as http://contoso.crm.grapecity.org).
This is basically determined by MS CRM by reading the registry value of the key [HKEY_LOCAL_MACHINESOFTWAREMicrosoftMSCRM]- IfdInternalNetworkAddress.

In reality, Microsoft Dynamics CRM will look at the IP address of the incoming request and match it against the internal range of the registry key specified. If the request is in the internal range of the registry key, it will give you a "Windows experience." If the IP address is external, it gives an "IFD experience."

This registry can be modified to switch between the windows and the IFD experiences (and this is supported :)). You will need to set the value for the "IfdInternalNetworkAddress" registry key in order to change the internal subnet of the IFD setting.

Philip Richrdson explains this well(Refer to : http://blog.philiprichardson.org/2007/12/20/switching-between-ifd-and-windows/)
For example, if the client is configured with an IP address of 192.168.1.2 (Subnet: 255.255.255.0):
When the internal range is 192.168.1.1-255.255.255.0 you will get a Windows experience. (assuming that this is the value which you provided in the config.xml file when Microsoft Dynamics CRM was installed.)
When the internal range is 192.168.1.1-255.255.255.255 you will get an IFD experience. This is because the client on the host operating system has an IP of 192.168.1.2 (Subnet: 255.255.255.0), which is outside the internal range.

Here are the two registry key modifications:
IFD Experience:
[HKEY_LOCAL_MACHINESOFTWAREMicrosoftMSCRM] "IfdInternalNetworkAddress"="192.168.1.1-255.255.255.255"

Windows Experience:
[HKEY_LOCAL_MACHINESOFTWAREMicrosoftMSCRM] "IfdInternalNetworkAddress"="192.168.1.1-255.255.255.0"

Tuesday, September 8, 2009

Using CRM Services to create or update records in large numbers

Recently, I implemented a plug in code which invoked auto creation of records from a contacts list (rather marketing lists based on MS CRM contacts) for my custom entity. The code worked well but it hanged whenever I considered a marketing list of more than 3000 contacts. The error logged read: Only one usage of each socket address (protocol/network address/port) is normally permitted.


Basically, the error was thrown when the creation process exhausted the limit of socket connections allowed by the IIS and the SDK still polled for another connection and consequentially timed out after a certain number of records were created. A quick workaround for this is to change the following entries in the registry:

HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort to 65534AndHKLM\System\CurrentControlSet\Services\Tcpip\Parameters\TCPTimedWaitDelay to be 30




The link : http://dmcrm.blogspot.com/2008/07/updating-records-in-mass-via-sdk.html also mentions a resolution of this by using the following code snippet:



int NUM_RETRY_ITERATIONS = 50;
int p = 0;
do
{
try
{
crmService.Create(customentity);
p = NUM_RETRY_ITERATIONS;
}
catch (Exception e)
{
p++;
if (p >= NUM_RETRY_ITERATIONS)
{
throw (e);
//WriteToFile("updateContact error: " + e.Message + " " + e.InnerException);
}
System.Threading.Thread.Sleep(500);
}
} while (p < NUM_RETRY_ITERATIONS);

IFD Implementation for custom web pages and Anonymous Access

When deploying my custom web pages for an IFD deployment, I got a FileLoadException (Exception from HRESULT: 0x80131401) on accessing the page in the browser.


Basically, this issue arose since anonymous access was somehow disabled for the “ISV/CustomPages” application in IIS while by default it is enabled for the Microsoft Dynamics CRM website.

This implied that my custom web site was using Windows NT Authentication, while the Microsoft Dynamics CRM Website was enabled for anonymous access. Hence, I got “Loading this assembly would produce a different grant set from other instances” on accessing any of my web pages from within MS CRM.

Simply turning on anonymous access for my custom website did the trick and rendered all my custom web pages correctly :)