Monday, March 14, 2011

FxCop 10.0 code analysis results are not shown in CCNET Build Report

I am using cruise Control .NET (V1.5.7256.1) with TFS 2008 and VS2010.  Integration is such that for each checkin CCNet gets latest version using sourcecontrol type="vsts", and build with MSBuild. My solution contains single project file, I have enabled option “Code Analysis on Build” from Code Analysis tab in VS2010 and selected “Microsoft Minimum Recommended Rules”.
Now FxCop (V10.0) obviously run and generate “[ProjectName].exe.CodeAnalysisLog.xml” file in bin\debug folder when build is successful. Using CC merge tool, I can integrate the results to BuildLog xml files. Everything is working upto this point.  I can see build XML and Fxcop report is integrated nicely.
Problem Statement: when I see build report in dash board, no Fxcop results are displayed. How to identify and integrate FxCop 10.0 xsl to display the results on HTML report is the issue.

I googled for some time and found, CCNet does support FxCop version 1.36 and not later than that. When I browsed to “C:\Program Files\CruiseControl.NET\webdashboard\xsl” folder, I can see “fxcop-report_1_36.xsl” file. So at another place, there was a clue to generate xsl for FxCop 10.0. Very simple, just create a copy of fxcop-report_1_36.xsl with new name “fxcop-report_10_0.xsl” and replace version number in new created file to “10.0”. Here is original code need to replace:
<xsl:variable name="fxcop.root" select="//FxCopReport[@Version = '1.36']" />
 - to -
<xsl:variable name="fxcop.root" select="//FxCopReport[@Version = '10.0']" />
Still no report is coming under Build Log
Then I reached to the conclusion, I should edit dashboard.config to under ccnet website in IIS, so I opened it and append fxcop10 xsl path as follows:

I saved the changes, Restarted CCNET service under SCM, then Reset IIS using command line. When I accessed the page, I can see the Build Report with Fxcop 10.0 static code analysis. Here is a snap:

 Great, isn't it :)

Thursday, March 3, 2011

CRM Discovery service, WCF Client and NTLM Authentication on LAN

First point was how I access the Dynamics CRM 4.0 Discovery Service? Here is the url provided in search engines:


This is a url that can work on CRM server itself and on intranet.
after adding this service reference in a plain c# project, here is bining information added in config file:

<binding name="CrmDiscoveryServiceSoap" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />

You can see default security mode is none. Let us try to build access this discovery service.
CrmDiscoveryServiceSoapClient discoSvc = new CrmDiscoveryServiceSoapClient();
NetworkCredential crmCredential = new NetworkCredential(User, Password, Domain);
discoSvc.ClientCredentials.Windows.ClientCredential = crmCredential;
discoSvc.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Identification;
RetrieveOrganizationsRequest orgrequest = new RetrieveOrganizationsRequest();
RetrieveOrganizationsResponse orgresponse = (RetrieveOrganizationsResponse)discoSvc.Execute(orgrequest);
OrganizationDetail myorg = new OrganizationDetail();
foreach (OrganizationDetail organizationDetail in orgresponse.OrganizationDetails)
if (organizationDetail.OrganizationName.Equals(orgname, StringComparison.OrdinalIgnoreCase))
             // ...

I get following exception while execution:
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate,NTLM'.
I replaced web.cofg security section, and it worked for me.
<security mode="TransportCredentialOnly">
  <transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />
  <message clientCredentialType="UserName" algorithmSuite="Default" />