Click here to Skip to main content
6,295,667 members and growing! (17,386 online)
Email Password   helpLost your password?
Web Development » User Controls » General     Intermediate License: The Code Project Open License (CPOL)

Ad Rotator Widget Control for BlogEngine.NET

By SALEKS

BlogEngine.NET Ad Rotator Control provides a simple interface for managing and rotating ads on the blog
HTML, C# 2.0, C# 3.0, Windows, .NET 2.0, .NET 3.0, ASP.NET, WebForms, Dev, SysAdmin
Posted:19 Dec 2008
Views:5,907
Bookmarked:13 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
4 votes for this article.
Popularity: 2.65 Rating: 4.40 out of 5

1

2
1 vote, 25.0%
3
1 vote, 25.0%
4
2 votes, 50.0%
5

Introduction

BlogEngine.NET is an open source .NET blogging project that was born out of a desire for a better blog platform. A blog platform with less complexity, easy customization, and one that takes advantage of the latest .NET features. Being an open source, BlogEngine.NET provides great level of customization and extensibility.

Starting a blog couple months ago, I start looking into available extensions you can download and implement into your own BlogEngine.NET installation. Browsing through the long list of available extensions, I was quite surprise not to find any extensions which would allow adding and managing ads on the blog.

Background

Thinking about the requirements I wanted from such a control, I came out with the following list:

  • Should support any Ad Provider
  • Should allow hide ads for authenticated users, to keep correct impression count
  • Should be easy to manage and allow to keep all my ad script in one repository
  • Should provide not only random but also weighted rotation, allowing to customize frequency with which each ad script is displayed to the users. The idea behind it is to distribute ad impressions between different providers to maximize revenue stream.

Using the Code

The widget consists of AdManagementBase.cs file with a set of common classes for the widget and “Sponsored Links” folder with widget code.

To install it, just copy AdManagementBase.cs into BlogEngine\App_Code\Extensions folder and then copy “Sponsored Links” folder to BlogEngine\widgets folder. The widget now should be available in the widget collection of BlogEngine.NET

InstallWidget.jpg Widget.jpg

To see it working, take a look at the Interview Patterns with C# blog.

Points of Interest

LoadWidget Method

BlogEngine.NET provides a very straight forward interface for implementing widgets and custom extensions. AdRotator class inherits from abstract class WidgetBase which is essentially a child of ASP.NET UserControl class. WidgetBase contains only one abstract method and two abstract properties which need to be implemented:

//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; }

The heart of the widget control is the LoadWidget method.

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;
}
}

Class WidgetBase isolates widget developers from implementation of settings storage retrieval mechanism by providing GetSettings() function which returns StringDictionary with widget settings specified on the edit screen. Unfortunately this interface works only with strings and doesn't have any internal logic to serialize complex objects. To solve this problem, AdManagement base class uses XmlSerializer and StringWriter to serialize list of Ad objects and persist it in widget settings collection.

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));
}

The check for CurrentPrincipal property CurrentPrincipal.Identity.IsAuthenticated allows to display default text instead of ads for all authenticated users and avoid false impressions.

AuthZUser.jpg

Editing Settings

As per BlogEngine documentation, the only way a widget can be editable is by adding a edit.ascx file to the widget folder. However, there are a couple more things that need to be done:

  1. Widget needs to override IsEditable property of WidgetBase class to return true
  2. Widget should contain edit.ascx file with base class inherited from WidgetEditBase
  3. Save method should be implemented to provide logic to save widget settings
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 widget overrides Save method and saves two parameters: collection of ad providers and boolean value indicating if the ads should be hidden for authenticated users:

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;
}

The Ad object also contains such information as name for the script you are using, JavaScript code snippet provided by ad network (Google, YPN, Microsoft, Bride, etc.) and the rotation weight. Use rotation weight to influence the ration of ads delivered from each ad provider. Note: If all of your scripts have weight equal to zero, the ads will have equal probability to be shown. If any of your scripts have weight greater than zero, all the ads with zero weight will not be shown at all.

EditScreen.jpg

Click here for the demo.

History

  • 20th December, 2008: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

SALEKS


Member

Location: United States United States

Other popular User Controls articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 4 of 4 (Total in Forum: 4) (Refresh)FirstPrevNext
GeneralThanks PinmemberJeffCirceo7:12 13 May '09  
GeneralNull reference exception fix PinmemberSALEKS20:47 31 Mar '09  
Generalsame problem Pinmemberkdutttomb8:48 24 Mar '09  
QuestionObject reference not set to an instance of an object. Pinmemberbcousins18:29 26 Jan '09  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 19 Dec 2008
Editor: Deeksha Shenoy
Copyright 2008 by SALEKS
Everything else Copyright © CodeProject, 1999-2009
Web10 | Advertise on the Code Project