I’ve been meaning to blog about this for a while but just haven’t gotten around to it. Have you ever needed to add a web part to a page during Feature activation? Of course you can do this declaratively using CAML but I usually prefer to do this stuff via code. The challenge is that occasionally you will need to activate the Feature outside the context of a web request – such as via STSADM – this becomes critical for certain web parts, such as earlier versions of the KPI List Web Part, which required a valid SPContext in order to be added to a page (this web part was fixed in the August 2008 Cumulative Update (or thereabouts) so that it no longer requires a valid SPContext object).
If you’re faced with adding a web part (or any other artifact) which requires a valid SPContext object outside of a web request than you can create your own context with the following three lines of code:
1: HttpRequest httpRequest = new HttpRequest("", web.Url, "");
2: HttpContext.Current = new HttpContext(httpRequest, new HttpResponse(new StringWriter()));
3: SPControl.SetContextWeb(HttpContext.Current, web);
public static void AddWebPart(SPWeb web, string page, string webPartXmlFile, string zone, int zoneId, bool deleteExistingIfFound) { bool cleanupContext = false; try { if (HttpContext.Current == null) { cleanupContext = true; HttpRequest httpRequest = new HttpRequest("", web.Url, ""); HttpContext.Current = new HttpContext(httpRequest, new HttpResponse(new StringWriter())); SPControl.SetContextWeb(HttpContext.Current, web); } using (SPLimitedWebPartManager manager = web.GetLimitedWebPartManager(page, PersonalizationScope.Shared)) { string err; XmlTextReader reader = null; System.Web.UI.WebControls.WebParts.WebPart wp; try { string webPartXml = File.ReadAllText(webPartXmlFile); webPartXml = webPartXml.Replace("${siteCollection}", web.Site.Url); webPartXml = webPartXml.Replace("${site}", web.Url); webPartXml = webPartXml.Replace("${webTitle}", HttpUtility.HtmlEncode(web.Title)); reader = new XmlTextReader(new StringReader(webPartXml)); wp = manager.ImportWebPart(reader, out err); if (!string.IsNullOrEmpty(err)) throw new Exception(err); } finally { if (reader != null) reader.Close(); } // Delete existing web part with same title so that we only have the latest version on the page foreach (System.Web.UI.WebControls.WebParts.WebPart wpTemp in manager.WebParts) { if (wpTemp.Title == wp.Title) { if (deleteExistingIfFound) manager.DeleteWebPart(wpTemp); else { wpTemp.Dispose(); return; } break; } wpTemp.Dispose(); } manager.AddWebPart(wp, zone, zoneId); } } finally { if (HttpContext.Current != null && cleanupContext) { HttpContext.Current = null; } } }



0 comments:
Post a Comment