Sunday, July 31, 2005

Summer holiday scope complete

My three weeks of summer holiday is over. It has been nice weather most of the time, only a few rainy days. The first two weeks in our boat down the Swedish west coast (bästkusten), with lazy days in the archipelago of Bohuslän. The last week included some slavery at home at the whim of my wife, plus a few days of trekking in Rondane.

Now it's back to work implementing MSCRM and SharePoint, but it is only six weeks until we go hunting grouse (Lagopus Lagopus) in
Finnmark.

PS! Congrats to my colleague Mads Nissen with becoming a Microsoft MVP.

Tuesday, July 05, 2005

Using SharePoint lists.asmx web service

SharePoint (WSS 2.0) provides several web services that gives you access to different parts of the object model and its data, without the need to use the object model directly and without worrying where the data is stored in a farm deployment. Getting started is a bit tricky, but here is a list of articles that will get you started:

In addition, these tools are priceless for helping with CAML and for viewing the real names of columns in the SharePoint list:

The real column names are those you see in the CAML output area of the U2U tool, and you must use these column names in the XML parameters of the web service methods (e.g. 'Name' is really called 'Title'). If you do not get the name right or reference the wrong list, you will get an error like this:

Exception of type Microsoft.SharePoint.SoapServer.SoapServerException was thrown.

<detail> <errorstring xmlns="...">No such field name.
No field was found with that name. Check the name, and try again.</errorstring><errorcode xmlns="...">0x81020014</errorcode</detail>

Note how easily Microsoft has left out an important piece of information: which field name ?

An important detail when programming against the SharePoint web services is to remember to set the .Url property of your web reference to point to the correct WSS team site. The lists.asmx web service is a virtual service and is by SharePoint magic available in all WSS sites, not only in the IIS virtual directory /_vti_bin/. In addition, remember to apply correct credentials for authentication.


Set the .Url like this (avoid getting //_vti_bin/):

_svcList.Url = siteUrl + "/_vti_bin/lists.asmx";
_svcList.Credentials = System.Net.CredentialCache.DefaultCredentials;

The standard SDK documentation of the lists web service is available on MSDN, along with the rest of the WSS web services.

Saturday, July 02, 2005

Finishing touches on VSTO-O deployment

My colleague Mads Nissen has posted additional details about how to deploy a VSTO Outlook 2003 solution to client PCs. The post shows how to use a custom action to set the CAS rights for the install directory, in addition to naming three more VSTO assembly dependencies beyond VSTAddin.DLL.

These details completes my previous posting on VSTO-O deployment.

Friday, June 10, 2005

Redemption still needed with Outlook VSTO 2005

One of the things that I had hoped would be improved in the VSTO 2005 Outlook toolkit was that several central MAPI fields should become exposed in the object model. These fields includes being able to change the sender (from) of an e-mail, getting the SMTP address of an Exchange user, getting the URL name of a message, etc.

These things are exactly as before, Microsoft has not added any new functionality to the toolkit, just made it .NET managed code and more reliable. This is 'by design' according to Microsoft, this was the default reply to my wishes during the alpha programme: "VSTO-O does not add any additional functionality to the object model".

During the testing I wanted to set the mail sender without using Redemption. After a suggestion by Sue Mosher I tried by granting a user 'send as' permissions on department mailboxes and changing the sender using the standard SentOnBehalfOfName in the ItemSend event handler, but this never worked. Ken Laws [MSFT] has confirmed that using SentOnBehalfOfName in the ItemSend event is too late, thus you still need Redemption to set this through extended MAPI. This property only works e.g. when set on a Outlook.MailItem created by code.

Changing the sender of an Outlook.MailItem object in ItemSend:

Redemption.SafeMailItem safeMail = new Redemption.SafeMailItemClass();
//Select the item to be modified
safeMail.Item = mailItem;
//fill in the e-mail address in 'From'
int tag = safeMail.GetIDsFromNames("{00020386-0000-0000-C000-000000000046}", "From");
tag = tag 0x1E; //the type is PT_STRING8
safeMail.set_Fields(tag, address);


Getting the SMTP address of an Exchange user from an Outlook.AddressEntry object:

//check if Exchange address
if (mailAddress.StartsWith("/o="))
{
//get SMTP address from MAPI
Redemption.MAPIUtils mapiUtils = new Redemption.MAPIUtils();
int PR_EMAIL = 0x39FE001E;
mailAddress = mapiUtils.HrGetOneProp(entry.MAPIOBJECT, PR_EMAIL).ToString();
mapiUtils.Cleanup();
}

The Outlook toolkit should be reviewed before RTM to add more of the most needed MAPI fields to the list of properties exposed in the object model. Please Microsoft VSTO-O team!