Custom Calendar Providers for Outlook 2007


So if you were using Stephen Toub’s Custom Calendar Provider sample for Outlook 2003, and you are testing out the awesome new Outlook 2007 features, you may have noticed that the code sample he provided doesn’t work any more. Stephen is planning to update the article for 2007 eventually, but until then, here’s the fix.


The GetList web service method is supposed to return a <Fields> node filled with <Field> nodes that describe each field in that list, including type information, display names, read-only properties, etc. In the sample above, Stephen is not returning the <Fields> node as a part of the response. The reason is that Outlook 2003 ignored this information when it was performing the sync. Outlook 2007 is a little more intelligent in this regard and it does need this information returned. It’s not a big deal when linking to a SharePoint Events list, because SharePoint always returns that data. In an effort to keep the code simple, Stephen ignored it.


So the answer is that we need to add that information back in. So what you’ll want to do is edit the WssListResponse.cs file as follows:



  1. Add a new private static method called AddFieldElement as follows:

  2.   /// <summary>
      /// Adds a Field node to the Fields parent node
      /// </summary>
      /// <param name=”parentDoc”>XmlDocument parent doc used for creating the new element</param>
      /// <param name=”parentNode”>The parent Fields node to which to add the new Field element</param>
      /// <param name=”type”>Type attribute</param>
      /// <param name=”colName”>ColName attribute</param>
      /// <param name=”name”>Name attribute</param>
      /// <param name=”displayName”>DisplayName attribute</param>
      /// <param name=”readOnly”>ReadOnly attribute</param>
      /// <param name=”hidden”>Hidden attribute</param>
      /// <param name=”fromBaseType”>FromBaseType attribute</param>
      /// <returns></returns>
      private static XmlElement AddFieldElement(XmlDocument parentDoc,XmlNode parentNode,string type, string colName, string name, string displayName,bool readOnly, bool hidden, bool fromBaseType)
      {
       XmlElement fieldEl = parentDoc.CreateElement(null,”Field”,_wssns);
       parentNode.AppendChild(fieldEl);


       if(type != null)  AddAttribute(fieldEl,null,”Type”,null,type);
       if(colName != null)  AddAttribute(fieldEl,null,”ColName”,null,colName);
       if(name != null)  AddAttribute(fieldEl,null,”Name”,null,name);
       if(displayName != null) AddAttribute(fieldEl,null,”DisplayName”,null,displayName);
       if(readOnly)   AddAttribute(fieldEl,null,”ReadOnly”,null,”TRUE”);
       if(hidden)    AddAttribute(fieldEl,null,”Hidden”,null,”TRUE”);
       if(fromBaseType)  AddAttribute(fieldEl,null,”FromBaseType”,null,”TRUE”);


       return fieldEl;
       
      }



  3. Modify the GetListDescription Method as follows:

  public static XmlNode GetListDescription(string title, Guid id)
  {
   // Create the response document
   XmlDocument doc = new XmlDocument();


   // Add a List element
   XmlNode list = doc.CreateElement(null, “List”,  _wssns);
   doc.AppendChild(list);


   // Add attributes about the list to the List element
   AddAttribute(list, null, “DocTemplateUrl”, null, “”);
   AddAttribute(list, null, “DefaultViewUrl”, null, “/Lists/” + id.ToString(“N”) + “/AllItems.aspx”);
   AddAttribute(list, null, “ID”, null, id.ToString(“B”));
   AddAttribute(list, null, “Title”, null, title);
   AddAttribute(list, null, “Description”, null, title);
   AddAttribute(list, null, “ImageUrl”, null, “/_layouts/images/itevent.gif”);
   AddAttribute(list, null, “Name”, null, id.ToString(“N”));
   AddAttribute(list, null, “BaseType”, null, “0”);
   AddAttribute(list, null, “ServerTemplate”, null, “106”);
   AddAttribute(list, null, “Created”, null, DateTime.MinValue.AddDays(2).ToString(“s”).Replace(“T”, ” “));
   AddAttribute(list, null, “Modified”, null, DateTime.MinValue.AddDays(3).ToString(“s”).Replace(“T”, ” “));
   AddAttribute(list, null, “LastDeleted”, null, DateTime.MinValue.AddDays(3).ToString(“s”).Replace(“T”, ” “));
   AddAttribute(list, null, “Version”, null, “0”);
   AddAttribute(list, null, “Direction”, null, “none”);
   AddAttribute(list, null, “ThumbnailSize”, null, “”);
   AddAttribute(list, null, “WebImageWidth”, null, “”);
   AddAttribute(list, null, “WebImageHeight”, null, “”);
   AddAttribute(list, null, “Flags”, null, “4096”);
   AddAttribute(list, null, “ItemCount”, null, “1”); // isn’t used, so no point in recomputing size of list
   AddAttribute(list, null, “AnonymousPermMask”, null, “”);
   AddAttribute(list, null, “RootFolder”, null, “/Lists/” + id.ToString(“N”));
   AddAttribute(list, null, “ReadSecurity”, null, “1”);
   AddAttribute(list, null, “WriteSecurity”, null, “1”);
   AddAttribute(list, null, “Author”, null, “1”);
   AddAttribute(list, null, “AnonymousPermMask”, null, “”);
   AddAttribute(list, null, “EventSinkAssembly”, null, “”);
   AddAttribute(list, null, “EventSinkClass”, null, “”);
   AddAttribute(list, null, “EventSinkData”, null, “”);
   AddAttribute(list, null, “EmailInsertsFolder”, null, “”);
   AddAttribute(list, null, “AllowDeletion”, null, “TRUE”);
   AddAttribute(list, null, “AllowMultiResponses”, null, “FALSE”);
   AddAttribute(list, null, “EnableAttachments”, null, “TRUE”);
   AddAttribute(list, null, “EnableModeration”, null, “FALSE”);
   AddAttribute(list, null, “EnableVersioning”, null, “FALSE”);
   AddAttribute(list, null, “Hidden”, null, “FALSE”);
   AddAttribute(list, null, “MultipleDataList”, null, “FALSE”);
   AddAttribute(list, null, “Ordered”, null, “FALSE”);
   AddAttribute(list, null, “ShowUser”, null, “TRUE”);


   //Create Fields node
   XmlElement fieldsNode = doc.CreateElement(null, “Fields”,  _wssns);
   list.AppendChild(fieldsNode);


   XmlElement tmpEl;


   //Append Fields
   tmpEl = AddFieldElement(doc,fieldsNode,”Counter”,”tp_ID”,”ID”,”ID”,true,false,true);
   tmpEl = AddFieldElement(doc,fieldsNode,”Text”,”nvarchar1″,”Title”,”Title”,false,false,true);
   tmpEl = AddFieldElement(doc,fieldsNode,”DateTime”,”tp_Modified”,”Modified”,”Modified”,true,false,true);
   AddAttribute(tmpEl,null,”StorageTZ”,null,”TRUE”);
   tmpEl = AddFieldElement(doc,fieldsNode,”DateTime”,”tp_Created”,”Created”,”Created”,true,false,true);
   AddAttribute(tmpEl,null,”StorageTZ”,null,”TRUE”);
   tmpEl = AddFieldElement(doc,fieldsNode,”User”,”tp_Author”,”Author”,”Created By”,true,false,true);
   AddAttribute(tmpEl,null,”List”,null,”UserInfo”);
   tmpEl = AddFieldElement(doc,fieldsNode,”User”,”tp_Editor”,”Editor”,”Modified By”,true,false,true);
   AddAttribute(tmpEl,null,”List”,null,”UserInfo”);
   tmpEl = AddFieldElement(doc,fieldsNode,”Integer”,”tp_Version”,”owshiddenversion”,”owshiddenversion”,true,true,true);
   AddAttribute(tmpEl,null,”SetAs”,null,”owshiddenversion”);
//   tmpEl = AddFieldElement(doc,fieldsNode,”Attachments”,”tp_HasAttachment”,”Attachments”,”Attachments”,true,false,true);
//   tmpEl = AddFieldElement(doc,fieldsNode,”ModStat”,”tp_ModerationStatus”,”_ModerationStatus”,”Approval Status”,true,true,true);
//   AddAttribute(tmpEl,null,”CanToggleHidden”,null,”TRUE”);
//   AddAttribute(tmpEl,null,”Required”,null,”FALSE”);
//   tmpEl = AddFieldElement(doc,fieldsNode,”Note”,”ntext1″,”_ModerationComments”,”Approver Comments”,true,true,true);
//   AddAttribute(tmpEl,null,”CanToggleHidden”,null,”TRUE”);
//   AddAttribute(tmpEl,null,”Sortable”,null,”FALSE”);
//   tmpEl = AddFieldElement(doc,fieldsNode,”Computed”,null,”Edit”,”Edit”,true,false,true);
//   AddAttribute(tmpEl,null,”Sortable”,null,”FALSE”);
//   AddAttribute(tmpEl,null,”Filterable”,null,”FALSE”);
//   AddAttribute(tmpEl,null,”AuthoringInfo”,null,”(link to edit item)”);
//   tmpEl = AddFieldElement(doc,fieldsNode,”Computed”,null,”LinkTitleNoMenu”,”Title”,true,false,true);
//   AddAttribute(tmpEl,null,”AuthoringInfo”,null,”(linked to item)”);
//   AddAttribute(tmpEl,null,”Dir”,null,””);
//   AddAttribute(tmpEl,null,”DisplayNameSrcField”,null,”Title”);
//   tmpEl = AddFieldElement(doc,fieldsNode,”Computed”,null,”LinkTitle”,”Title”,true,false,true);
//   AddAttribute(tmpEl,null,”AuthoringInfo”,null,”(linked to item with edit menu)”);
//   AddAttribute(tmpEl,null,”DisplayNameSrcField”,null,”Title”);
//   AddAttribute(tmpEl,null,”ClassInfo”,null,”Menu”);
//   tmpEl = AddFieldElement(doc,fieldsNode,”Computed”,null,”SelectTitle”,”Select”,true,true,true);
//   AddAttribute(tmpEl,null,”AuthoringInfo”,null,”(web part connection)”);
//   AddAttribute(tmpEl,null,”Dir”,null,””);
//   AddAttribute(tmpEl,null,”Sortable”,null,”FALSE”);
//   AddAttribute(tmpEl,null,”CanToggleHidden”,null,”TRUE”);
//   tmpEl = AddFieldElement(doc,fieldsNode,”Integer”,”tp_InstanceID”,”InstanceID”,”InstanceID”,true,true,true);
//   AddAttribute(tmpEl,null,”Sortable”,null,”TRUE”);
//   AddAttribute(tmpEl,null,”Filterable”,null,”TRUE”);
//   AddAttribute(tmpEl,null,”Min”,null,”0″);
//   AddAttribute(tmpEl,null,”Max”,null,”99991231″);
//   tmpEl = AddFieldElement(doc,fieldsNode,”Number”,”tp_ItemOrder”,”Order”,”Order”,false,true,true);
   tmpEl = AddFieldElement(doc,fieldsNode,”Guid”,”tp_Guid”,”GUID”,”GUID”,true,true,true);
   tmpEl = AddFieldElement(doc,fieldsNode,”DateTime”,”datetime1″,”EventDate”,”Begin”,false,false,true);
   AddAttribute(tmpEl,null,”Format”,null,”DateTime”);
   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
   AddAttribute(tmpEl,null,”Required”,null,”TRUE”);
   AddAttribute(tmpEl,null,”Filterable”,null,”FALSE”);
   AddAttribute(tmpEl,null,”FilterableNoRecurrence”,null,”TRUE”);
   tmpEl = AddFieldElement(doc,fieldsNode,”DateTime”,”datetime2″,”EndDate”,”End”,false,false,true);
   AddAttribute(tmpEl,null,”Format”,null,”DateTime”);
   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
   AddAttribute(tmpEl,null,”Filterable”,null,”FALSE”);
   AddAttribute(tmpEl,null,”FilterableNoRecurrence”,null,”TRUE”);
   tmpEl = AddFieldElement(doc,fieldsNode,”Note”,”ntext2″,”Description”,”Description”,false,false,false);
   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
   AddAttribute(tmpEl,null,”Sortable”,null,”False”);
   tmpEl = AddFieldElement(doc,fieldsNode,”Text”,”nvarchar”,”Location”,”Location”,false,false,false);
   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
   tmpEl = AddFieldElement(doc,fieldsNode,”Recurrence”,”bit1″,”fRecurrence”,”Recurrence”,false,false,false);
   AddAttribute(tmpEl,null,”DisplayImage”,null,”recur.gif”);
   AddAttribute(tmpEl,null,”HeaderImage”,null,”recur.gif”);
   AddAttribute(tmpEl,null,”ClassInfo”,null,”Icon”);
   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
   AddAttribute(tmpEl,null,”NoEditFormBreak”,null,”TRUE”);
//   tmpEl = AddFieldElement(doc,fieldsNode,”CrossProjectLink”,”bit2″,”WorkspaceLink”,”Workspace”,false,false,false);
//   AddAttribute(tmpEl,null,”Format”,null,”EventList”);
//   AddAttribute(tmpEl,null,”DisplayImage”,null,”mtgicon.gif”);
//   AddAttribute(tmpEl,null,”HeaderImage”,null,”mtgicnhd.gif”);
//   AddAttribute(tmpEl,null,”ClassInfo”,null,”Icon”);
//   AddAttribute(tmpEl,null,”Title”,null,”Meeting Workspace”);
//   AddAttribute(tmpEl,null,”Filterable”,null,”TRUE”);
//   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
   tmpEl = AddFieldElement(doc,fieldsNode,”Integer”,”int1″,”EventType”,”Event Type”,false,true,false);
   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
   tmpEl = AddFieldElement(doc,fieldsNode,”Guid”,”uniqueidentifier1″,”UID”,”UID”,false,true,false);
   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
   tmpEl = AddFieldElement(doc,fieldsNode,”DateTime”,”datetime3″,”RecurrenceID”,”Recurrence ID”,false,true,false);
   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
   AddAttribute(tmpEl,null,”CalType”,null,”1″);
   AddAttribute(tmpEl,null,”Format”,null,”ISO8601Gregorian”);
   tmpEl = AddFieldElement(doc,fieldsNode,”Boolean”,”bit3″,”EventCanceled”,”Event Canceled”,false,true,false);
   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
   tmpEl = AddFieldElement(doc,fieldsNode,”Integer”,”int2″,”Duration”,”Duration”,false,true,false);
   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
   tmpEl = AddFieldElement(doc,fieldsNode,”Note”,”ntext3″,”RecurrenceData”,”RecurrenceData”,false,true,false);
   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
   tmpEl = AddFieldElement(doc,fieldsNode,”Integer”,”int3″,”TimeZone”,”TimeZone”,false,true,false);
   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
   tmpEl = AddFieldElement(doc,fieldsNode,”Note”,”ntext4″,”XMLTZone”,”XMLTZone”,false,true,false);
   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
//   tmpEl = AddFieldElement(doc,fieldsNode,”Integer”,”int4″,”MasterSeriesItemID”,”MasterSeriesItemID”,false,true,false);
//   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
//   tmpEl = AddFieldElement(doc,fieldsNode,”URL”,”nvarchar3″,”Workspace”,”WorkspaceUrl”,false,true,false);
//   AddAttribute(tmpEl,null,”Sealed”,null,”TRUE”);
//   AddAttribute(tmpEl,null,”ColName2″,null,”nvarchar4″);


   // Return the XML
   return doc;
  }


You’ll notice that I have commented out a few lines in this method. There are probably more lines that can be commented out. We’re not returning all the information that SharePoint would return, but it’s not all useful to Outlook, so why clog the ethernet lines with useless data?!


Anyway, once you’ve made those modifications, you can recompile the web application and you should be golden!

Comments (26)

  1. Stephen Toub says:

    I’ve received several emails from folks who have been successfully using my Outlook Calendar Provider

  2. I made the changes listed, and it still works fine in Outlook 2003, but in Outlook 2007 I still get:

    Task ‘SharePoint’ reported error (0x8000FFFF) : ‘An error occurred either in Outlook or Windows SharePoint Services. Contact the Windows SharePoint Services site administrator.’

    The wss log gives a fairly unhelpful error of:

     <?xml version=”1.0″ ?>

    – <errors>

     <error>An error occurred either in Outlook or Windows SharePoint Services. Contact the Windows SharePoint Services site administrator.</error>

     </errors>

    I have emailed you a more verbose “bug report” and am hopeful you will be able to assist.

  3. pcreehan1 says:

    Nigel, That’s the same error you get without the Fields node added at all. My guess is that Outlook is expecting your GetList response to be formatted slightly differently.

    I haven’t received your email yet, so I’m not sure what your "bug report" contains.

    Are you implementing the Application event log sample? Does the View Events link work?

  4. pcreehan1 says:

    Can you please use the contact form to send your "bug report"? I did not receive your email.

  5. Nigel.Swinson says:

    It occurred to me that Outlook 2007 was launched in November, so there was likely a later version than my beta 2 build 4017.  I am now running with build 4518 and am pleased to say that your changes work :o)  

    Not only do they work, but I was able to apply them to Stephen Toub’s OutlookContactProvider too, and am serving up my own custom data.

    I’m told Outlook 2007 supports writing to WSS lists, so how do you specify that the contacts/events folder is writable, which presumably would then show the outlook edit form, and result in calls to UpdateListItems().  At the moment if I try to make changes Outlook tells me "This SharePoint list is read-only in Outlook".

    Thanks for your help thus far :o)

  6. Peter says:

    "The GetList web service method is supposed to return a <Fields> node filled with <Field> nodes"

    Where can you see the documentation about what is supposed to be returned ?

    I am trying to make the Contact list work in Outlook 2007 but fails (I do not get any error message, but simply never sees any data coming into outlook from my web service, which is based on the outlook 2003 example at http://blogs.msdn.com/toub/archive/2004/12/22/330125.aspx ).

    How can I see what kind of data that actually gets sent when you are using a real sharepoint contact list ?

    (it works without problem so if I can see the data being sent back and forth, then maybe I can see if I will need some "Fields" elements for the contacts also)

  7. pcreehan1 says:

    What I did for the example above was that I called the GetList web service with javascript, and got the response back and examined it. I just used a standard Events list with no added columns from a standard Team site. You could probably do the same thing with a standard Contacts list.

  8. Claudio says:

    Following you example I can get it working with Office 2007 but I still have a problem:

    In Office 2003 I can see all contact info

    In Office 2007 I can see anly the FullName filed

    Can you help me?

    Many thanks.

    Claudio

  9. pcreehan1 says:

    Claudio, You realize the example above is for a custom Calendar provider, right? For a contacts list, obviously the Fields you would return would be different.

  10. Claudio says:

    I understand my troubles but how should I modify the GetListDescription method to work as Outlook Contact Provider ?

    Many thanks

  11. pcreehan1 says:

    You will have to figure that out in a way that makes sense for what you’re trying to do. You could extend that method to take an additional parameter that tells you what type of list you are asking for and then construct the XML data based on that, or you could just store the XML for the different types of lists separately in an XML file, load them up and return them. This was just a hard-coded sample to show you the method to use in taking advantage of the stssync capabilities of Outlook. It’s up to you to run with it and test it out.

    If you’re asking how to get the list data for a Contacts list, just call the GetList web service on a standard contacts list in SharePoint and observe the return value. SharePoint is going to return all the data about that list including field information and View information. At this point, it’s not important to include the View information, because Outlook doesn’t care about it. In fact, the reason that I created this post was that in Outlook 2003, it didn’t even care about the Fields collection, it just assumed certain fields were present. Outlook 2007 got a little smarter about it and started paying attention to the Fields that GetList returns. That’s why we needed to add that node into the response that our web service is returning to include the Fields node.

    Hope that helps.

  12. James says:

    Thanks for this write up. For the guy who wanted the contacts fields, here are the defaults:

    tmpEl = AddFieldElement(doc, fieldsNode, “Counter”, “tp_ID”, “ID”, “ID”, true, false, true);

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar1”, “Title”, “Title”, false, false, true);

    tmpEl = AddFieldElement(doc, fieldsNode, “DateTime”, “tp_Modified”, “Modified”, “Modified”, true, false, true);

    AddAttribute(tmpEl, null, “StorageTZ”, null, “TRUE”);

    tmpEl = AddFieldElement(doc, fieldsNode, “DateTime”, “tp_Created”, “Created”, “Created”, true, false, true);

    AddAttribute(tmpEl, null, “StorageTZ”, null, “TRUE”);

    tmpEl = AddFieldElement(doc, fieldsNode, “User”, “tp_Author”, “Author”, “Created By”, true, false, true);

    AddAttribute(tmpEl, null, “List”, null, “UserInfo”);

    tmpEl = AddFieldElement(doc, fieldsNode, “User”, “tp_Editor”, “Editor”, “Modified By”, true, false, true);

    AddAttribute(tmpEl, null, “List”, null, “UserInfo”);

    tmpEl = AddFieldElement(doc, fieldsNode, “Integer”, “tp_Version”, “owshiddenversion”, “owshiddenversion”, true, true, true);

    AddAttribute(tmpEl, null, “SetAs”, null, “owshiddenversion”);

    tmpEl = AddFieldElement(doc, fieldsNode, “Guid”, “tp_Guid”, “GUID”, “GUID”, true, true, true);

    if (!isCalendar)

    {

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar3”, “FirstName”, “First Name”, false, false, false);

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar5”, “FullName”, “Full Name”, false, false, false);

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar6”, “Email”, “E-mail Address”, false, false, false);

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar8”, “Company”, “Company”, false, false, false);

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar9”, “JobTitle”, “Job Title”, false, false, false);

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar10”, “WorkPhone”, “Work Phone”, false, false, false);

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar11”, “HomePhone”, “Home Phone”, false, false, false);

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar12”, “CellPhone”, “Mobile Phone”, false, false, false);

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar13”, “WorkFax”, “Fax Number”, false, false, false);

    tmpEl = AddFieldElement(doc, fieldsNode, “Note”, “ntext2”, “WorkAddress”, “Address”, false, false, false);

    AddAttribute(tmpEl, null, “NumLines”, null, “2”);

    AddAttribute(tmpEl, null, “Sortable”, null, “FALSE”);

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar14”, “WorkCity”, “City”, false, false, false);

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar15”, “WorkState”, “State”, false, false, false);

    AddAttribute(tmpEl, null, “NumLines”, null, “2”);

    AddAttribute(tmpEl, null, “Sortable”, null, “TRUE”);

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar16”, “WorkZip”, “Postal Code”, false, false, false);

    tmpEl = AddFieldElement(doc, fieldsNode, “Text”, “nvarchar17”, “WorkCountry”, “Country”, false, false, false);

    tmpEl = AddFieldElement(doc, fieldsNode, “URL”, “nvarchar18”, “WebPage”, “Web Page”, false, false, false);

    AddAttribute(tmpEl, null, “ColName2”, null, “nvarchar19”);

    tmpEl = AddFieldElement(doc, fieldsNode, “Note”, “ntext3”, “Comments”, “Notes”, false, false, false);

    AddAttribute(tmpEl, null, “Sortable”, null, “FALSE”);

    }

  13. pcreehan1 says:

    Thanks, James, for taking the time to do the leg work on this one!

  14. Steve says:

    Firstly, thank you for the great code!

    What are the chances of investigating for us the minimal requirements for reading contacts into outlook using the syssync 1.2 protocol as opposed to this 1.0 method. (i’d LOVE to have two way sync happening)

    I have done everything i can to handcraft the xml copied from a sample web request from a sharepoint 2007 site. Cant seem to get it happening (GetList seems to be the first issue in replicating).

    Am i asking too much?

  15. Michael Vesely says:

    Thanks, all of you for your work, that helped a lot.

    I combined Calendar and Contacts into one ASP.NET 2.0 application and added the tweaks for OL 2007. Tested with 2003 went perfectly OK, test with 2007 is still a todo. I can post the code, if there is interest but I’d like to add a couple of aditional calendar fields. Has anyone found the definitions for the ‘show as’ (Free, Busy, …) and Category (I want to set the colors)?

    Would be great, Michael

  16. Francois Gaumond says:

    I would like to know if it’s possible to made with post folders. I have an Sharepoint 2007 discussion list and I want to edit the default view to include more fields present in Sharepoint. Is it possible to this in same way as for contacts.

    Thanks

  17. pcreehan1 says:

    Francois, I’m not sure what you’re asking. Are you asking if it’s possible to use stssync with a Discussion List to display the items in your Outlook contacts folder, or are you asking how to create a custom view in SharePoint?

    If the former, I suppose it’s possible as long as you handle the mapping from the different fields into fields that Outlook would expect to see for a contact.

    If the latter, then I’d point you to http://msdn.microsoft.com/sharepoint. Look for the documentation on CAML. You can create and edit SharePoint views with CAML, but it is not easy at all. It may be easier to use a tool such as SharePoint Designer or FrontPage. I’m not sure if this answers your question though.

  18. Stefan Hogedal says:

    Is there any way of putting the events in the main calendar? My impression is that this is needed if the consumer wants to sync with a mobile device.

  19. pcreehan1 says:

    To the best of my knowledge, that is correct, Stefan. And to answer your question, there’s not a way to directly have the stssync put appointments into the calendar. Outlook creates a wrapped PST specifically for SharePoint synchronization. The only way you’d be able to do it is if you then have code that synchronizes between your calendar and the SharePoint events calendar in the PST. This is not an easy undertaking. If you just need the one-way sync, you may be able to just wipe/replace from a new calendar folder in your mailbox. That would be easier code to write, but only allows for one-way sync, and any changes made by the end user would be erased at the next sync.

  20. James Ecker says:

    Michael I didn’t see any other person posting the request, so I will. Can you post your code for Calendar and Contacts into one ASP.NET 2.0?

    Thank you in advance,

    James

  21. Wiz/dumb says:

    Many of you have been using the Custom Calendar Provider samples created by Stephen Toub and I: Stephen

  22. Wilson says:

    Hi,

    got the web service running fine now..

    but I have problem getting the Category field working for the contact.

    AddAttribute(node, Nothing, "ows_Category", Nothing, "Business")

    AddAttribute(node, Nothing, "ows_Categories", Nothing, "Business")

    but both doesn’t seems to work..  does anyone know what is the correct name for the Category ows_ field for sharepoint?

    I am running XP Office 2003

    thanks

  23. Wilson says:

    Hi,

    got the web service running fine now..

    but I have problem getting the Category field working for the contact.

    AddAttribute(node, Nothing, "ows_Category", Nothing, "Business")

    AddAttribute(node, Nothing, "ows_Categories", Nothing, "Business")

    but both doesn’t seems to work..  does anyone know what is the correct name for the Category ows_ field for sharepoint?

    my os is XP with office 2003

    thanks

  24. pcreehan1 says:

    Hi Wilson, remember that there are a fixed set of fields that are synchronized. If the field is not part of the original schema for the Contacts list, then it may not be automatically synchronized. The list of fields increases with Outlook 2007, but it’s still fixed. Check out my latest blog entry where we have published exactly how to build these types of services. There may be more detail in the specification. (I haven’t had time to read it yet myself.) 🙂

    http://blogs.msdn.com/pcreehan/archive/2008/04/08/stssync-for-the-masses-toub-s-revenge.aspx

  25. Wiz/dumb says:

    So I’ve finally done it. I made the first stab at a two-way stssync protocol server. You can get it here:

  26. sancti says:

    I want to implement the outlook calnedar in C#. Can you please tell me how can i do this.

    thanks