I have modified Carlos’s XmlCatalogPart (Carlos is one of the members of the Microsoft ASP.Net team for only displaying WebParts that a user is authorized to add. I also add the support of adding user control as a WebPart, here is the code:
namespace MyControls
{
using System;
using System.Web.Caching;
using System.ComponentModel;
using System.Collections.Generic;
using System.Xml;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
///
/// Catalog for reading WebParts from an Xml Document
///
public class XmlCatalogPart : CatalogPart
{
XmlDocument document;
WebPartDescriptionCollection _description;
Dictionary<string,WebPart> _loadedWebparts;
///
/// Overrides the Title to display Xml Catalog Part by default
///
public override string Title
{
get
{
string title = base.Title;
return string.IsNullOrEmpty(title) ? "Xml Catalog Part" : title;
}
set
{
base.Title = value;
}
}
///
/// Specifies the Path for the Xml File that contains the declaration of the WebParts,
/// more specifically the WebPartDescriptions
///
[
UrlProperty(),
DefaultValue("")]
public string DataFile
{
get
{
object o = ViewState["DataFile"];
return o == null ? "" : (string)o;
}
set
{
ViewState["DataFile"] = value;
}
}
///
/// Creates a new instance of the class
///
public XmlCatalogPart()
{
}
///
/// Returns the WebPartDescriptions
///
public override WebPartDescriptionCollection GetAvailableWebPartDescriptions()
{
if (this.DesignMode)
{
return new WebPartDescriptionCollection(new object[] {
new WebPartDescription("1", "Xml WebPart 1", null),
new WebPartDescription("2", "Xml WebPart 2", null),
new WebPartDescription("3", "Xml WebPart 3", null)});
}
if (_description == null)
this.GetWebParts();
return this._description;
}
private void GetWebParts()
{
XmlDocument document = GetDocument();
WebPartDescription description = null;
List<WebPartDescription> list = new List<WebPartDescription>();
this._loadedWebparts = new Dictionary<string, WebPart>();
foreach (XmlElement element in document.SelectNodes("/parts/part"))
{
WebPart webPart = CreateWebPartFromElement(element);
if ((webPart != null) && ((base.WebPartManager == null) || base.WebPartManager.IsAuthorized(webPart)))
{
description = new WebPartDescription(webPart);
list.Add(description);
this._loadedWebparts.Add(description.ID, webPart);
}
}
this._description = new WebPartDescriptionCollection(list);
}
private WebPart CreateWebPartFromElement(XmlElement element)
{
WebPart webPart = null;
string webPartType = element.GetAttribute("type");
string webpartId = element.GetAttribute("id");
if (webPartType.LastIndexOf(".ascx") > 0)
{
Control control = this.Page.LoadControl(webPartType);
control.ID = webpartId;
if (base.WebPartManager != null)
webPart = base.WebPartManager.CreateWebPart(control);
}
else
{
Type type = Type.GetType(webPartType);
webPart = Activator.CreateInstance(type, null) as WebPart;
}
webPart.ID = webpartId;
webPart.Title = element.GetAttribute("title");
webPart.CatalogIconImageUrl = element.GetAttribute("imageUrl");
webPart.AuthorizationFilter = element.GetAttribute("authorizationFilter");
return webPart;
}
///
/// Returns a new instance of the WebPart specified by the description
///
public override WebPart GetWebPart(WebPartDescription description)
{
if (this._loadedWebparts == null)
this.GetWebParts();
return this._loadedWebparts[description.ID];
}
///
/// private function to load the document and cache it
///
private XmlDocument GetDocument()
{
string file = Context.Server.MapPath(this.DataFile);
string key = "__xmlCatalog:" + file.ToLower();
XmlDocument document = Context.Cache[key] as XmlDocument;
if (document == null)
{
using (CacheDependency dependency = new CacheDependency(file))
{
document = new XmlDocument();
document.Load(file);
Context.Cache.Add(key, document, dependency,
Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
}
}
return document;
}
}
}
parts.xml
<?xml version="1.0" encoding="utf-8" ?>
<parts>
<part id="1" title="My Lottery WebPart" authorizationFilter="Administrator" imageUrl="image1.gif" type="MyWebParts.LotteryPicker" />
<part id="2" title="My Weather WebPart" authorizationFilter="Everyone" imageUrl="image2.gif" type="MyWebParts.WeatherWebPart" />
<part id="3" title="My User Control WebPart" authorizationFilter="Everyone" imageUrl="image3.gif" type="~/MyWebUserControl.ascx" />
</parts>
In the example above I use the WebPartManager’s IsAuthorized method to check if a the user can see a WebPart. Take a look at the following post on my blog for using the IsAuthorized method to carete your custom authorization logic:
How to hide a WebPart based on roles