BlogEngine.NET 的广告轮播控件
BlogEngine.NET 广告轮播控件提供了一个简单的界面来管理和轮播博客上的广告。
引言
BlogEngine.NET 是一个开源的 .NET 博客项目,它的诞生源于对更好的博客平台的追求。它更简单、易于自定义,并且充分利用了最新的 .NET 功能。作为一个开源项目,BlogEngine.NET 提供了高度的自定义和扩展性。
几个月前,我开始写博客,并开始查看可以下载并集成到我的 BlogEngine.NET 安装中的可用扩展。浏览了大量的可用 扩展,我惊讶地发现没有一个扩展允许在博客上添加和管理广告。
背景
考虑了对此类控件的要求后,我列出了以下几点:
- 应支持任何广告提供商
- 应允许隐藏已登录用户的广告,以保持正确的展示次数统计
- 应易于管理,并允许我将所有广告脚本保存在一个存储库中
- 应提供不仅随机,而且加权轮播,允许自定义每个广告脚本向用户显示的频率。这样做的目的是在不同提供商之间分配广告展示,以最大化收入流。
Using the Code
该控件包含一个名为 AdManagementBase.cs 的文件,其中包含一组控件的通用类,以及一个名为“Sponsored Links”的文件夹,其中包含控件的代码。
要安装它,只需将 AdManagementBase.cs 复制到 BlogEngine\App_Code\Extensions 文件夹,然后将“Sponsored Links”文件夹复制到 BlogEngine\widgets 文件夹。现在,该控件应该可以在 BlogEngine.NET 的控件集合中找到。
要查看其工作效果,请查看 Interview Patterns with C# 博客。
关注点
LoadWidget 方法
BlogEngine.NET 为实现控件和自定义扩展提供了非常直接的接口。AdRotator
类继承自 abstract
类 WidgetBase
,后者本质上是 ASP.NET UserControl
类的子类。WidgetBase
只包含一个 abstract
方法和两个 abstract
属性需要实现。
//This method works as a substitute for Page_Load.
//You should use this method for data binding etc. instead of Page_Load.
public abstract void LoadWidget();
// Gets the name, must be exactly the same as the folder that contains the widget
public abstract string Name { get; }
// Gets whether or not the widget can be edited.
public abstract bool IsEditable { get; }
控件的核心是 LoadWidget
方法。
public override void LoadWidget()
{
ASPCache aspCache=new ASPCache(this.Page);
StringDictionary settings = GetSettings();
Boolean hideForAuthenticatedUsers= true;
List<Ad> ads = AdManagementBase.DeSerializeAds
(settings[AdManagemenConstants.AdCollectionKey]);
ads.ForEach(delegate(Ad ad) { totalWeight += ad.RWeight; });
Boolean.TryParse(settings[AdManagemenConstants.HideAdsForAuthZUsersKey],
out hideForAuthenticatedUsers);
adManager = new AdManagementBase(aspCache, ads);
if (!IsPostBack)
{
if ((!System.Threading.Thread.CurrentPrincipal.Identity.IsAuthenticated) ||
(!hideForAuthenticatedUsers))
ShowAds(totalWeight);
else
adHolder.InnerHtml = AdManagemenConstants.AuthZUserMessage;
}
}
WidgetBase
类通过提供 GetSettings()
函数,将控件开发人员从设置存储检索机制的实现中分离出来。该函数返回一个 StringDictionary
,其中包含在编辑屏幕上指定的控件设置。不幸的是,此接口仅处理 string
,并且没有内部逻辑来序列化复杂对象。为了解决这个问题,AdManagement
基类使用 XmlSerializer
和 StringWriter
将 Ad 对象列表序列化并持久化到控件设置集合中。
public static string SerializeAds(List<Ad> ads)
{
if ((ads == null) || (ads.Count == 0)) return string.Empty;
XmlSerializer serializer = new XmlSerializer(typeof(List<Ad>));
StringWriter stream = new StringWriter();
serializer.Serialize(stream, ads);
return stream.ToString();
}
public static List<Ad> DeSerializeAds(string serializedStream)
{
if (string.IsNullOrEmpty(serializedStream)) return new List<Ad>();
XmlSerializer serializer = new XmlSerializer(typeof(List<Ad>));
return (List<Ad>)serializer.Deserialize(new StringReader(serializedStream));
}
通过检查 CurrentPrincipal
属性 CurrentPrincipal.Identity.IsAuthenticated
,可以为所有已登录用户显示默认文本而不是广告,从而避免错误的展示次数统计。

编辑设置
根据 BlogEngine 文档,控件可编辑的唯一方法是在控件文件夹中添加一个 edit.ascx 文件。然而,还有一些其他事情需要做:
- 控件需要重写
WidgetBase
类的IsEditable
属性以返回true
。 - 控件应包含一个 edit.ascx 文件,其基类继承自
WidgetEditBase
。 - 应实现
Save
方法以提供保存控件设置的逻辑。
public abstract class WidgetEditBase : UserControl
{
// Saves the basic widget settings such as the Title.
public abstract void Save();
// Get settings from data store
public StringDictionary GetSettings()
{
...
}
// Saves settings to data store
protected virtual void SaveSettings(StringDictionary settings)
{
...
}
public static event EventHandler<EventArgs> Saved;
// Occurs when the class is Saved
public static void OnSaved()
}
SponsoredLinks
控件重写了 Save
方法,并保存了两个参数:广告提供商的集合和一个布尔值,指示是否应隐藏已登录用户的广告。
public override void Save()
{
doUpdate();
StringDictionary settings = GetSettings();
settings[AdManagemenConstants.AdCollectionKey] =
AdManagementBase.SerializeAds(adCollection);
settings[AdManagemenConstants.HideAdsForAuthZUsersKey] =
cbAuthZAds.Checked.ToString();
SaveSettings(settings);
HttpRuntime.Cache.Remove(AdManagemenConstants.WidgetSettingsKey);
HttpRuntime.Cache.Remove(AdManagemenConstants.SerializedAdsKey);
CurrentIndex = 0;
}
Ad
对象还包含诸如所用脚本的名称、广告网络(Google、YPN、Microsoft、Bride 等)提供的 JavaScript 代码片段以及轮播权重等信息。使用轮播权重可以影响每个广告提供商显示的广告的比例。注意:如果所有脚本的权重都等于零,则广告的显示概率相等。如果任何脚本的权重大于零,则所有权重为零的广告将不会显示。

点击此处查看 演示。
历史
- 2008 年 12 月 20 日:首次发布