My blog has moved!

Visit http://blog.adamroderick.com/ and update your bookmarks.

Friday, February 13, 2009

Slides for BizTalk Basics

Here is a slide deck I use when I provide a very short (~30 min) introduction to BizTalk. One of the slides provides some animation showing how a message makes its way into and then out of BizTalk. Other slides go over BizTalk artifacts Schemas, Map, Pipelines, and Orchestrations, and include screenshots of simple scenarios.

BizTalk Basics

Easily Debug Feature Event Receivers in SharePoint

One of the painful points of SharePoint development is debugging Feature Event Receivers. If you run the feature activation/deactivation from the command line, you can’t attach to the process fast enough. If you run the feature activation from the web, you have to attach to the w3p .exe process, go through multiple screens, and tie up the process while debugging.

A better option is to use the project settings of the project your feature receiver is in. Choose the Debug tab, then in Start external program, put in the path to STSADM.exe (C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\stsadm.exe. In the command line arguments, put in the arguments for the command you want to run. If it is feature activation, the arguments are –o ActivateFeature –url http:// -filename \feature.xml.

To run, right-click on your project, choose Debug > Start New Instance. The project will build, the feature will begin activation, and Visual Studio will automatically attach to the correct process, stopping at any breakpoints you have set in your Feature Receiver.

Labels:

Wednesday, February 4, 2009

Changing a Page's Layout Programmatically

We wanted to change a page's page layout in code. Here is the method I used to do it. You will need to add a reference to Microsoft.SharePoint.dll and Microsoft.SharePoint.Publishing.dll. The only two parameters the method needs are the full URL of the page you want to change, and the name of the new page layout:


/// <summary>
/// Changes a page's layout to the one specified in newLayoutName
/// </summary>
/// <param name="fullPageUrl">full url of the page</param>
/// <param name="newLayoutName">The name of the new page layout</param>
/// <returns>a string containing the name of the page's resulting layout</returns>
public string ChangePageLayout(string fullPageUrl, string newLayoutName)
{
string retval = string.Empty;
string pageName = System.IO.Path.GetFileName(fullPageUrl);

// get the site collection for the page
using (SPSite siteColl = new SPSite(fullPageUrl))
{
// because we got our SPSite using the full URL of the page,
// the OpenWeb method returns the correct site
using (SPWeb site = siteColl.OpenWeb())
{
PublishingWeb pubSite = PublishingWeb.GetPublishingWeb(site);

try
{
PageLayout layout = GetPageLayout(site, newLayoutName);
if (null != layout)
{
PublishingPage page = pubSite.GetPublishingPages(GetPublishingPageByNameQuery(pageName))[0];
ForceCheckOut(page);

// switch the layout
page.Layout = layout;

retval = page.Layout.Name;
page.Update();
ForceApprove(page);
}
else
{
throw new Exception(string.Format("Page Layout {0} does not exist.", newLayoutName));
}


}
catch (ArgumentOutOfRangeException ex)
{
throw new Exception(string.Format("Page {0} does not exist.", fullPageUrl));
}

}
}
return retval;
}


The helper methods that I use in the above method are GetPublishingPageByNameQuery, which returns a formatted SPQuery:


/// <summary>
/// Returns a nicely formatted SPQuery
/// </summary>
/// <param name="pageName">The name (including extension) of the page you are looking for</param>
/// <returns>string of XML to assign to the Query property of an SPQuery object</returns>
private string GetPublishingPageByNameQuery(string pageName)
{
System.Text.StringBuilder oSb = new System.Text.StringBuilder();

oSb.Append(" <Where>");
oSb.Append(" <Eq>");
oSb.Append(" <FieldRef Name=\"FileLeafRef\" />");
oSb.Append(string.Format(" <Value Type=\"File\">{0}</Value>", pageName));
oSb.Append(" </Eq>");
oSb.Append(" </Where>");

return oSb.ToString();
}


ForceCheckout, ForceApprove, and GetPageLayout:


public static void ForceCheckOut(PublishingPage page)
{
try
{
page.CheckOut();
}
catch (SPException ex)
{
page.CheckIn(&quot;forced check in to update page template&quot;);
page.CheckOut();
}
}
public static void ForceApprove(PublishingPage page)
{
try { page.CheckIn(string.Empty); }
catch (Exception ex) { }
try { page.ListItem.File.Publish(string.Empty); }
catch (Exception ex) { }
try { page.ListItem.File.Approve(string.Empty); }
catch (Exception ex) { }
}
public static PageLayout GetPageLayout(SPWeb site, string pageLayoutName)
{
PageLayout retval = null;
PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(site);
PageLayout[] layouts = pubWeb.GetAvailablePageLayouts();
foreach (PageLayout availableLayout in layouts)
{
if (availableLayout.Name.Equals(pageLayoutName))
{
retval = availableLayout;
}
}
return retval;
}

Labels: