I will explain what you need to do to integrate WSS team-sites into MSCRM, and which modifications you should make to the web-part pages (WPP) and document libraries (doc-libs) of a team-site to make them well-behaved parts of MSCRM.
Our MSCRM-WSS integration is based on using some intermediate "staging" .ASPX pages that are the targets for e.g. the MSCRM <NavBarItem> element's URL attribute. We typically used two pages, one for doc-libs and one for other collaboration features of SharePoint:
<!-- The Account Left Nav Bar -->
<NavBar ValidForCreate="0" ValidForUpdate="1">
<NavBarItem Icon="/_imgs/ico_18_1.gif" Title="Document Archive" Url="http://london/Objectware.Mscrm.SharePoint/TeamSiteSharedDocuments.aspx" Id="Account.SharedDocs"/>
<NavBarItem Icon="/_imgs/ico_18_9.gif" Title="Collaboration" Url="http://london/Objectware.Mscrm.SharePoint/TeamSiteSummary.aspx" Id="Account.ViewTeamSite"/>
<NavBarItem Icon="/_imgs/ico_18_9.gif" Title="Links" Url="http://london/Objectware.Mscrm.SharePoint/TeamSiteSummary.aspx" Id="Account.ViewLinks"/>
Note that the PassParams attribute of v1.2 is now obsolete, and that the object type and guid now always get passed to the target page. Note the Id attribute; it is central in making the integration flexible. Use the attribute to pass different "tokens" to the staging-page to allow the page to provide different parts of the SharePoint team-site as the response. The parameters are passed as a querystring. Get the passed data in the Page_Load event of your .ASPX page:
string guid = Request.QueryString["oId"];
string type = Request.QueryString["oType"];
string tabSet = Request.QueryString["tabSet"];
Note that the Id attribute has the key tabSet in the URL querystring. Note also that the tabSet value gets the suffix "area", e.g. Account.ViewLinks becomes Account.ViewLinksarea. The oId value is the entity record GUID and the oType value is the type of the entity. Some of the most used types are:
- Account = 1
- Contact = 2
- Opportunity = 3
- Incident (case) = 112
We also use a team-site generator made by Mads Nissen to allow a user to create new team-sites directly from inside MSCRM should the team-site not exists. The method shown below is used to check whether a team-site exists or not for e.g. a specific account. Lately, we have started using K2.net workflow to get more flexibility and power in the team-site creation process.
Your staging-page should use <identity impersonate="true"> in the relevant WEB.CONFIG file to ensure that you assert team-site access as the logged on MSCRM user. You could use the SharePoint object model to check if the site exists and if the user is a member. I have chosen the simpler method of using the HttpWebRequest of the System.Net namespace and checking for exceptions, making some simple assumptions:
public static void CheckTeamSiteUrl(string url)
string response = "";
HttpWebResponse httpResponse = null;
//assert: user have access to URL
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url);
httpRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
httpResponse = (HttpWebResponse)httpRequest.GetResponse();
throw new ApplicationException("HTTP 403 Access denied, URL: " + url, ex);
//if here, the URL is correct and the user has access
StreamReader stream = new StreamReader(httpResponse.GetResponseStream());
response = stream.ReadLine(); // .ReadToEnd();
throw new ApplicationException("HTTP 404 Page not found, URL: " + url, ex);
if(response.ToLower() == "<html><body>the web site that is referenced here is not in the configuration database.</body></html>")
throw new ApplicationException("HTTP 404 Team-site not found, URL: " + url, null);
Note that WSS won't respond with a proper HTTP 404 error when the team-site does not exist. Rather, WSS responds with a valid page with a single line of text explaining that there is no such team-site in the SharePoint database.
If the CheckTeamSiteUrl method returns failure, a new team-site is generated from a WSS template (.STP) using the standard SharePoint web-services. The WSS template contains one or more web-part-pages (WPP) tailored for integration into MSCRM (see below).
If the CheckTeamSiteUrl method returns success, do a simple redirect to the actual target page within the WSS team-site.
You should tailor the WPPs that you integrate into MSCRM for these reasons:
- To remove the SharePoint "chrome": i.e. the page header, top menu, search, left menu, etc
- To configure the custom MSCRM view(s) of the doc-lib to use only basic column types rather than the "edit" column types, to keep the navigation options simple and controllable
- To configure doc-lib toolbars to be suitable for inline navigation in MSCRM
- To ensure that all hyperlinks are suitable for navigation within the MSCRM frame: if a link is not suitable for inline navigation, apply a target="_blank" attribute to it
Do not hesitate to remove the SharePoint "Modify shared page" menu link. The toolbox can always be summoned using this querystring: ?mode=edit&PageView=Shared&toolpaneview=2 (see SharePoint tweaks).
Also try this nifty little SharePoint querystring trick: ?contents=1