Friday, August 31, 2007

What is good to know about SPUtility.FormatDate

Today, while developing a custom web part, I’ve decided that it would be handy to use SPUtility.FormatDate to format all dates, and avoid dealing with String.Format and CultureInfo. And it actually was! Except one small issue, it’s good to know about: SPUtility.FormatDate will not only format specified date according to regional settings used in specific web, but it also assumes that provided time is UTC one, and will convert it to local time of the web, analyzing it’s time zone.
So if you already have a local time, you should convert it to UTC first:

using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

SPSite site = new SPSite("http://localhost");
SPWeb web = site.RootWeb;
DateTime dt = DateTime.Now;
string dateStr = SPUtility.FormatDate(web, web.RegionalSettings.TimeZone.LocalTimeToUTC(dt), SPDateFormat.DateTime);

Monday, August 27, 2007

Adding groups programmatically

Trying to add a group to SharePoint programmatically I’ve found an interesting issue – newly created group was not shown in Groups quick launch, but it was present in the list of all groups. After some time of analyzing SPWeb and SPGroup classes, have found an interesting point. Only groups which are associated with current web are shown in its quick launch. Other site groups are shown in the list of all groups (you can access it by clicking "More…" link in Groups quick launch). So if you want your newly created group to be accessible not only through the list of all groups, but also in Groups quick launch of some webs, you should add it to the collection of associated groups for specific web. This can be done by executing the following:

SPSite site = new SPSite("http://localhost");
SPWeb web = site.OpenWeb();
SPUser user = web.CurrentUser;
web.SiteGroups.Add("MyGroup", user, user, "My description");
SPGroup g = web.SiteGroups["MyGroup"];
web.AssociatedGroups.Add(g);
web.Update();

Don’t forget to call Update for each web, you have modified an associated groups collection to.

Tuesday, August 21, 2007

Managing web parts programmatically

Programming for SharePoint developers sometimes need to manage web parts on site pages from code. The most common tasks to perform are adding a web part, removing a web part and exporting/importing web part’s xml. In this post I’ll show how you can achieve this.

All tasks with web parts are performed through a web part manager. So first of all, you should get a web part manager for the page, you want to manage web parts in. For example:

using Microsoft.SharePoint;
using System.Web.UI.WebControls.WebParts;
using System.Collections.Generic;
using System.Xml;
using System.IO;

SPSite site = new SPSite("http://localhost");
SPWeb web = site.RootWeb;
SPFile file = web.GetFile("default.aspx");
if(!file.Exists)
{
Console.WriteLine("File not found!");
}
else
{
Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager man = file.GetLimitedWebPartManager(PersonalizationScope.Shared);
// ...
}
Now we’ve got a web part manager man, and can use it to perform all actions with web parts on default.aspx page.

To add web parts you should use AddWebPart method of the web part manager:

Microsoft.SharePoint.WebPartPages.ListViewWebPart lvwp = new Microsoft.SharePoint.WebPartPages.ListViewWebPart();
SPList list = web.Lists["MyList"];
lvwp.Title = "My ListViewWebPart";
lvwp.ListName = list.ID.ToString("B").ToUpper();
lvwp.ViewGuid = list.DefaultView.ID.ToString("B").ToUpper();
lvwp.ViewType = Microsoft.SharePoint.WebPartPages.ViewType.Html;
man.AddWebPart(lvwp,"Right",1);
In this sample, we’ve added a list view web part to the right web part zone of default.aspx page. Pay attention that ListName is actually the GUID of our list, and both ListName and ViewGuid should contain strings in upper case. Otherwise you will get an exception from ListViewWebPart class.

To remove web parts you should use DeleteWebPart method of the web part manager class:

List wpForRemove = new List();
foreach(WebPart wp in man.WebParts)
if(wp.Title+"" == "")
wpForRemove.Add(wp);
foreach(WebPart wp in wpForRemove)
man.DeleteWebPart(wp);
This code will remove all web parts with blank title from default.aspx page.

Finally, to export xml code of the web part, you can use ExportWebPart method of the web part manager class. To export all settings from your web part, you should set its ExportMode property value to All. Otherwise you would be able to export only non sensitive data, or will get an exception during export operation. To export all web parts from default.aspx page to files, you can execute:

foreach(WebPart wp in man.WebParts)
{
WebPartExportMode tempMode = wp.ExportMode;
wp.ExportMode = WebPartExportMode.All;
string fileName = String.Format(@"C:\Temp\{0}_{1}.txt", wp.ID, wp.Title);
XmlTextWriter wrt = new XmlTextWriter(fileName,Encoding.UTF8);
man.ExportWebPart(wp,wrt);
wrt.Close();
wp.ExportMode = tempMode;
}
Xml code of a web part can be used to import some web part to another page as well. To do it, just use ImportWebPart method of the web part manager, passing XmlReader with xml code of a web part as a parameter.