Monday, November 8, 2010

SharePoint - 401: Unauthorized downloading Infopath file with WebClient.DownloadFile

Today, I got an "401: Unauthorized" exception when calling the WebClient.DownloadFile method to download an Infopath file from SharePoint, even if I provided the correct permissions (setting the WebClient.Credentials property).

This was because of the Infopath Forms Server feature in MOSS 2007 Enterprise edition. This feature redirects to the /_layouts/FormServer.aspx page, apparently this was resulting in an Unauthorized exception.

A workaround is to add "?NoRedirect=true" to the url, like this: http://ServerName/sites/SiteCollection/FormLibrary/Form1.xml?NoRedirect=true.

More information about some Query Parameters you can use on the /_layouts/FormServer.aspx page: http://msdn.microsoft.com/en-us/library/ms772417.aspx

Monday, September 20, 2010

CRM 2011 beta - integration with SharePoint 2010 (the real stuff)

The SharePoint Solution for the integration with CRM 2011 is fixed, you can download it here: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=0c7dcc45-9d41-4e2e-8126-895517b4274c&displayLang=en

Some screenshots of the layout of the Sharepoint folder in CRM (looking good!):







Tuesday, September 14, 2010

CRM 2011 beta - integration with SharePoint 2010

Microsoft CRM 2011 beta is available. I was curious about the SharePoint integration in CRM 2011. Unfortunately, the Sharepoint solution delivered with the beta release wasn't working (I was getting errors "Could not load file or assembly 'Microsoft.Crm.SharePoint.CrmGridFeature' or one of its dependencies. Strong name signature could not be verified. The assembly may have been tampered with, or it was delay signed but not fully signed with the correct private key", a reply from Microsoft CRM Support is added, saying there are some unsigned bits - http://social.microsoft.com/Forums/en-US/crm2011beta/thread/8d195290-6bfa-4d4b-a1a9-ad21bb296ad2), hope they will post an update soon!

The SharePoint solution is required to have CRM creating Sharepoint folders automatically when adding a new record. However, it is possible to add Sharepoint locations manually to a record too. Some screenshots:













Wednesday, March 31, 2010

SharePoint 2010: CamlQuery on External List

When running a CamlQuery on an External List, we got an error "The given key was not present in the dictionary.".

Apparently you have to specify the <ViewFields> tag in the CamlQuery.ViewXml property. So you have to specify the <ViewFields></ViewFields> tag with the right fields in the ViewXml property.

For example, this will NOT work:
camlQuery.ViewXml = @"
<Method Name='ReadList'/>
<Query>
<Where>
<Contains>
<FieldRef Name='Name'/>
<Value Type='Text'>AAS</Value>
</Contains>
</Where>
<OrderBy>
<FieldRef Name='Name'/>
</OrderBy>
</Query>
</View>";


... but this will work:
camlQuery.ViewXml = @"
<Method Name='ReadList'/>
<Query>
<Where>
<Contains>
<FieldRef Name='Name'/>
<Value Type='Text'>AAS</Value>
</Contains>
</Where>
<OrderBy>
<FieldRef Name='Name'/>
</OrderBy>
</Query>
<ViewFields>
<FieldRef Name='AccountID' ListItemMenu='TRUE' LinkToItem='TRUE'/>
<FieldRef Name='Name'/>
</ViewFields>


</View>";


To find out the XML you have to use for the <ViewFields> tag, you can add a ListView webpart of your External List to a page and grab the <ViewFields> XML by opening the page in SharePoint Designer:


I read this solution here: http://blog.trivadis.com/blogs/stefanfrutiger/archive/2010/03/15/sharepoint-2010-bcs-zugriff-auf-externe-daten-aus-einer-silverlight-4-applikation.aspx. Luckely, I understand a little bit German ;-)

Saturday, January 23, 2010

Validate url to be used for a SharePoint site (replace illegal characters)


I made a function to check if a string contains illegal characters to be used as an URL for a new SharePoint site. This is useful to use when calling the Webs.Add function to programmatically create a new site in SharePoint where a user has provided the desired site url.

I took a look at the Create Site page in SharePoint. SharePoint calls a JavaScript function "IndexOfIllegalCharInUrlLeafName", which can be found in the "commonvalidation.js" on your SharePoint server. After the function call, SharePoint will check for a '+' character separately.

This is the function i've created. Illegal characters are replaced with a '-' character.


(you can download the code in a text file here)

Wednesday, December 23, 2009

MS CRM 4.0 - Call RetrieveMultiple webservice in JavaScript helper function

I've developed a function to call the CRM RetrieveMultiple webservice in JavaScript without having to write the XML yourselve: "CallRetrieveMultipleWebService".

The function generates the XML for you. You just have to pass the entity to query, an array of columns to get, the filter operator and the array of conditions.

Here's the function with an example how to call the webservice to find contacts with a first- and lastname as conditions.




function CallRetrieveMultipleWebService(queryEntityName, queryColumnSetAttributes, queryFilterOperator, conditionArray) {
if (queryEntityName != null && queryColumnSetAttributes != null) {
var columnSetAttributesString = "";
for (var i = 0; i < queryColumnSetAttributes.length; i++) {
columnSetAttributesString += "" + queryColumnSetAttributes[i] + "";
}
var conditionsString = "";
if (conditionArray != null) {
conditionsString = "";
for (var i = 0; i < conditionArray.length; i++) {
conditionsString += "";
conditionsString += "" + conditionArray[i][0] + "";
conditionsString += "" + conditionArray[i][1] + "";
conditionsString += "";
var valuesArray = conditionArray[i][2];
for (var j = 0; j < valuesArray.length; j++) {
conditionsString += "" + valuesArray[j] + "";
}
conditionsString += "
";
conditionsString += "
";
}
conditionsString += "
";
}

var xml = "" +
"" +
"" +
GenerateAuthenticationHeader() +
" " +
" " +
" " +
" " + queryEntityName + "" +
" " +
" " +
columnSetAttributesString +
"
" +
"
" +
"" +
"" + queryFilterOperator + "" +
conditionsString +
"
" +
"
" +
"
" +
"
" +
"
" +
"";

var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
xmlHttpRequest.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple");
xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
xmlHttpRequest.send(xml);
var resultXml = xmlHttpRequest.responseXML;
// Check for errors.
var errorCount = resultXml.selectNodes('//error').length;
if (errorCount != 0) {
var msg = resultXml.selectSingleNode('//description').nodeTypedValue;
alert(msg);
}
// return results
else {
return resultXml;
}
}
}

//function to find a contact, using the CallRetrieveMultipleWebService function:
function FindContact(firstnameToSearch, lastnameToSearch)
{
//define the entity name to query
var queryEntityName = "contact";
//set up the array of columns to get
var queryColumnSetAttributes = new Array();
queryColumnSetAttributes[0] = "contactid";
queryColumnSetAttributes[1] = "telephone1";
//define the filter operator
var queryFilterOperator = "And";
//set up the array of confitions in the query
var queryConditions = new Array();
//define 2 conditions: add 2 items to the array:
queryConditions[0] = new Array("firstname", "Equal", new Array(firstnameToSearch));
queryConditions[1] = new Array("lastname", "Equal", new Array(lastnameToSearch));
//Call function CallRetrieveMultipleWebService
var resultXml = CallRetrieveMultipleWebService(queryEntityName, queryColumnSetAttributes, queryFilterOperator, queryConditions);
var teleponeValueToSet = null;
var results = resultXml.getElementsByTagName('BusinessEntity');
if (results.length > 0) {
//do something with the found contacts
//example: show an alert with the telephone number of the first found contact
var telephone = results[0].selectSingleNode('./q1:telephone1') == null ? null : results[0].selectSingleNode('./q1:telephone1').nodeTypedValue;
if (telephone != null) {
alert(telephone);
}
}
else {
alert('No contact ' + firstnameToSearch + ' ' + lastnameToSearch + ' found.');
}
}

Tuesday, December 8, 2009

MS CRM 4.0: Publish workflow not working after updating to Rollup 7

After updating my CRM 4.0 software to Rollup 7, the publishing of workflows failed.

Apparently, this is a known issue. Found the solution in this forum: https://community.dynamics.com/forums/t/18135.aspx

Saturday, November 21, 2009

MS CRM: Insufficient permissions Assign Case

When you get a "Insufficient permissions" message when you assign a case, check that your current user's permission roles has Read permissions on Queue.

When you get a message about user permissions, you can find out what permissions are needed for the action you want to do by doing the steps described on http://support.microsoft.com/kb/953962

Saturday, November 7, 2009

Thursday, August 20, 2009

Problem with Sharepoint Datasheet View after installing an Office 2007 component when Office 2003 is already installed

When we installed Project 2007 on a machine with Office 2003 already installed, the Datasheet view didn't work anymore: "The list cannot be displayed in Datasheet view for one or more of the following reasons: A datasheet component compatible with Windows SharePoint Services is not installed, your browser does not support ActiveX controls, or support for ActiveX controls is disabled".

Apparently, the Datasheet view component does not work when Office 2003 and Office 2007 components both are installed on the client machine.

This is the solution:

1. Install Office 2003, include the Windows SharePoint Services Support

2. Install the Office 2007 component(s) (in my case, this was Project 2007), without Windows SharePoint Services Support!

3. Now re-run the Office 2003 installation. Choose Repair and then select the Reinstall option.

Tuesday, June 23, 2009

MS CRM 4.0 Custom Workflow Activity assembly update not executing the new code

When you are developing a custom workflow activity for MS CRM 4.0, you have to register this activity with the Plugin Registration Tool provided by MS CRM 4.0 SDK.

When I changed the code of my workflow activity, and tried the Update action in de Plugin Registration Tool, the new code did not execute, it executed the cached version of the previous code. To get your new code to run, perform an IISRESET and restart the Microsoft CRM Asynchronous Processing Service after updating your assembly in the Plugin Registration Tool. It took me a while to find this out, but it’s actually quite logical.

MS CRM 4.0 VPC - remove the 'crm' host header

On the CRM Demo VPC 2009, there is a host header 'crm' defined to redirect to the crm-srv-01:5555 website (the CRM application). When you want to change this, you'll need to do this steps:

- Change the host header in the Internet Information Services window. Select Properties on the CRM Web site, go to the Web Site tab and click Advanced. Hit Edit... and remove the 'crm' host header value

Because you removed your host header, the workflows won't work anymore, because the configured webservice url still points to the host header value. Perform these steps to change this:

- Change this Registry keys in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSCRM: ServerUrl to http://localhost:5555/MSCRMServices; LocalSdkHost to localhost; LocalSdkPort to 5555

- Go to the SQL Server Management Studio, and execute this queries on the MSCRM_CONFIG database (This is not supported! Please take a backup of this database before executing the queries):

USE MSCRM_CONFIG

Update DeploymentProperties SET NVarCharColumn = 'localhost:5555' WHERE ColumnName = 'AsyncSdkRootDomain'

Update DeploymentProperties SET NvarCharColumn = 'localhost:5555' WHERE ColumnName = 'ADSdkRootDomain'

Update DeploymentProperties SET NvarCharColumn = 'localhost:5555' WHERE ColumnName = 'ADWebApplicationRootDomain'

(queries found on http://www.sadev.co.za/content/workflow-doesnt-work-imports-never-happen-emails-dont-flow-and-outlook-clients-cannot-connec)

- Perform an IISRESET and Restart the Microsoft CRM Asynchronous Processing Service.

Friday, April 3, 2009

Microsoft Dynamics CRM 4.0 - enable tracing / logging

To enable logging on your Microsoft Dynamics CRM 4.0 server, you can follow this instructions: http://support.microsoft.com/kb/907490/en-us. A handy tool is written to do this instead of changing the registry keys yourselve: http://blogs.msdn.com/benlec/archive/2008/03/04/crmdiagtool4-for-microsoft-crm-4-0-has-been-released.aspx.

However, the tool configures your server to log all the stuff it's processing. This is because the registry value of TraceCategories is set to "*:Verbose". Set the registry value to "*:Error" if you only want the errors to be logged. If you want to log errors and warnings, set the value to "*:Error;*:Warnings".

The default location is set to [drive]:\Program Files\Microsoft Dynamics CRM Server\Trace. To change this, change the value of the TraceDirectory registry setting.


Monday, March 30, 2009

Sharepoint - An update conflict has occurred, and you must re-try this action.

I got this error today on a restored MOSS environment, when trying to add an existing content database:

An update conflict has occurred, and you must re-try this action. The object SPWebApplication Name=WEBAPPLICATIONNAME Parent=SPWebService is being updated by DOMAIN\USER, in the w3wp process, on machine SERVERNAME. View the tracing log for more information about the conflict.

I found this KB to solve this issue: http://support.microsoft.com/kb/939308

"This issue occurs if the contents of the file system cache on the front-end servers are newer than the contents of the configuration database. After you perform a system recovery, you may have to manually clear the file system cache on the local server."

Sharepoint - An update conflict has occurred, and you must re-try this action.

I got this error today on a restored MOSS installation, when trying to add an existing content database:
An update conflict has occurred, and you must re-try this action. The object SPWebApplication Name=WEBAPPLICATIONNAME Parent=SPWebService is being updated by DOMAIN\USER, in the w3wp process, on machine SERVERNAME. View the tracing log for more information about the conflict.
I found this KB to solve this issue: http://support.microsoft.com/kb/939308
"This issue occurs if the contents of the file system cache on the front-end servers are newer than the contents of the configuration database. After you perform a system recovery, you may have to manually clear the file system cache on the local server."

Sharepoint - An update conflict has occurred, and you must re-try this action.

I got this error today on a restored MOSS installation, when trying to add an existing content database:

An update conflict has occurred, and you must re-try this action. The object SPWebApplication Name=WEBAPPLICATIONNAME Parent=SPWebService is being updated by DOMAIN\USER, in the w3wp process, on machine SERVERNAME. View the tracing log for more information about the conflict.

I found this KB to solve this issue: http://support.microsoft.com/kb/939308

"This issue occurs if the contents of the file system cache on the front-end servers are newer than the contents of the configuration database. After you perform a system recovery, you may have to manually clear the file system cache on the local server."

Wednesday, March 25, 2009

Operating system error 1330(error not found) on RESTORE DATABASE in SQLcmd

A colleague of mine had this problem today (and found a solution!):

While trying to restore a database from a UNC path that’s not in the same domain as your database server, you might get the following error:

1> RESTORE DATABASE DatabaseName FROM DISK = '\\Server\Dump\DatabaseName.bak' WITH REPLACE

2> go

Msg 3201, Level 16, State 2, Server ServerName, Line 1

Cannot open backup device '\\Server\Dump\DatabaseName.bak'. Operating system error 1330(error not found).

Msg 3013, Level 16, State 1, Server ServerName, Line 1

RESTORE DATABASE is terminating abnormally.

Error not found, quite handy.

Note that on that network share “Everyone” has read rights (also on NTFS). So the file can be read from explorer. SQLcmd tries to use the domain user, and only that user for some reason.

The solution lies in the creation of a user account on the non-domain machine, with the same name as the domain user. (Never mind the domain prefix). Set the password, and you’re off!

Thursday, March 5, 2009

SharePoint Dispose Checker Tool

"SPDisposeCheck is a tool to help you to check your assemblies that use the SharePoint API so that you can build better code."

Thursday, January 29, 2009

Today in CAML query

I had to use [Today] in a CAML query. I tried configuring the query with the U2U Caml Query Builder 2007, this was the output:

<Where>
      <Eq>
         <FieldRef Name='Modified' />
         <Value Type='DateTime'>[Today-120Day(s)]</Value>
      </Eq>
</Where>

But this did not work when a tried to run the query in code (SPQuery). I used this query instead, and it worked fine:

<Where>
      <Eq>
         <FieldRef Name='Modified' />
         <Value Type='DateTime'><Today OffsetDays="-120"/></Value>
      </Eq>
</Where>