数据库驱动的横幅旋转控件






4.92/5 (16投票s)
一个数据库驱动的横幅轮播控件,它基于特定的时间进行旋转(而不是在页面刷新时)。每个横幅都有一个显示时间(以秒为单位)来切换到下一个。
引言
在本文中,我想介绍我的横幅轮播控件。它的构思与 ASP.NET AdRotator 控件不同。这个控件是数据库驱动的,横幅会在特定时间进行轮播(而不是在页面刷新时)。每个横幅都有一个显示时间(以秒为单位)来切换到下一个横幅(JavaScript 在客户端进行轮播)。
源代码(ASP.NET 服务器控件项目)和用于测试该控件的 ASP.NET 网站已附在本文顶部。我将分步解释以下内容:
- 控件功能
- 如何使用
- 使用该控件的不同方法
- ASP.NET 服务器控件(类库)解释
控件功能
- 数据库驱动:横幅的规格,如宽度、高度以及是否可点击,都来自数据库,横幅列表也是如此。横幅从数据库加载一次,然后在客户端进行轮播。
- 支持大多数图片格式(JPG、GIF、BMP 和 PNG,以及 Flash 文件 (swf))。
- 缓存:用户可以启用控件中的缓存并指定缓存时长。这将减少数据库的负载。
- 每个横幅的点击计数器功能。
- 支持多语言。
- 完全可定制:开发人员可以控制其显示方式,垂直和水平重复,即使没有加载横幅也要保留横幅区域,并根据页面 URL、查询字符串和任何用户定义的条件指定横幅显示条件。
如何使用
- 将 DLL 文件“BannerRotatorControl.dll”复制到 ASP.NET 应用程序的“bin”文件夹。
- 在您的 ASPX 页面中注册该控件
<%@ Register TagPrefix="BMS" Namespace="BannerRotatorControl"
Assembly="BannerRotatorControl" %>
<BMS:BannerRotator runat="server" ID="banner1"
ConnectionString="<%$ ConnectionStrings:bms_db %>"
BannersLanguage="en" LocationCode="TOP"
BannerImagesURL="<%$ appSettings:bms_data %>"
BannerClickFile="~/click.aspx" ScriptsPath="/scripts/"
ShowOnlyActivatedBanners="true" />
BannerRotator
控件有五个必须设置的属性
ConnectionString
:包含横幅控件表的数据库连接字符串。(文件 bms_db.mdf、bms_db.ldf 包含在源代码中。)BannersLanguage
和LocationCode
:这些是必填属性。它们是主要属性,它们告诉BannerRotator
根据以下表从数据库读取数据Widthpx
Heightpx
NoAds_image
:这将控制即使该区域没有横幅,也要保留横幅区域。BannerImagesURL
:此属性告诉控件横幅图片文件的位置 URL。我已将上面的属性设置为从 web.config 的appSettings
键读取。
BMS_BANNERS_AREAS 包含横幅区域列表。在上述 ASP.NET 控件中,我设置了 BannersLanguage="en" LocationCode="TOP"
,这会告诉控件读取 lang="en"
和 location_code="TOP"
(高亮显示的那一行)的横幅区域记录,并根据这些记录字段中指定的信息绘制横幅区域。
<add key="bms_data" value="https:///biznet-data/bms_test/{0}/banners/"/>
“biznet-data”是 IIS 中创建的一个虚拟目录,指向文件夹“c:\Biznet_data\bms_test\en\banners\”。请注意,我使用了 {0} 来替换为横幅的语言。
上述 ASP.NET 控件代码中的其他一些属性包括
BannerClickFile
:这将指定横幅是否可点击。这是您 ASP.NET 网站中点击文件 ASPX 页面的路径。在那里,您需要编写代码来更新横幅点击次数并重定向到指定的 URL 链接。
protected void Page_Load(object sender, EventArgs e)
{
string urlstr = BannerRotatorControl.BannerRotator.UpdateBannerClick(
ConfigurationManager.ConnectionStrings["bms_db"].ToString());
if (!string.IsNullOrEmpty(urlstr))
Response.Redirect(urlstr);
}
ScriptsPath
:如果您计划在横幅控件中使用 Flash 文件,此属性很重要。您应该为 Flash 加载器指定 Flash JavaScript 脚本路径。ShowOnlyActivatedBanners
:如果只想显示已激活的横幅,请将其设置为 true;否则设置为 false 以显示所有横幅(如果您在 Banner Management Admin 网站中使用横幅轮播,请将其设置为 false)。使用 BannerRotator 控件的不同方法
我们可以在不同的场景中使用该控件;我将列出最常见的几种:
- 单个预留横幅区域轮播多个横幅
- 将显示第一个横幅“BCCI_en_ad_eztrade468X60.jpg”,持续 3 秒,并且由于“
link_url
”设置为“http://www.eztrade.bh/”,因此它是可点击的。 - 第二个横幅是“bcci_en_shops_eztrade.gif”,显示 2 秒,由于“
link_url
”为 null,它不可点击。 - 最后一个是“bcci_en_banner1.swf”(一个 Flash 横幅),显示 7 秒。
- 然后它将再次循环。
- 多个横幅区域,每个区域只有一个横幅
- 多个预留横幅区域,多个横幅
- 第一个显示的横幅是“bcci_en_btn.jpg”,持续 4 秒,并且由于“
link_url
”设置为“http://www.bahraintradanet.com/”,因此它是可点击的。 - 第二个横幅是“bcci_en_gtn.jpg”,持续 6 秒,并且由于“
link_url
”设置为“http://www.gulftradanet.com/”,因此它是可点击的。 - 然后它将再次循环。
- 有条件地在横幅区域中显示横幅
PageURL
:这将告诉横幅控件在“BMS_BANNER_DISPLAY_CRITERIAS
”表中查找“criteria_code
”等于“PageURL
”的记录,并将当前的 ASPX 页面 URL 与“criteria_value
”字段进行比较。如果匹配,则可以显示此行的banner_id
。QueryString
:这将告诉横幅控件在“BMS_BANNER_DISPLAY_CRITERIAS
”表中查找“criteria_code
”等于“QueryString
”的记录,并检查当前 ASPX 页面 URL 查询字符串名称是否与“ParameterName
”匹配。然后,它将查询字符串值与“criteria_value
”字段进行比较。如果匹配,则可以显示此行的banner_id
。Session
:这将告诉横幅控件在“BMS_BANNER_DISPLAY_CRITERIAS
”表中查找“criteria_code
”等于“Session
”的记录,并检查是否存在名称与“ParameterName
”相同的会话对象。然后它将比较会话对象的值与“criteria_value
”字段。如果匹配,则可以显示此行的banner_id
。Cookie
:这将告诉横幅控件在“BMS_BANNER_DISPLAY_CRITERIAS
”表中查找“criteria_code
”等于“Cookie
”的记录,并检查是否存在名称与“ParameterName
”相同的 cookie 对象。然后它将比较 cookie 对象的值与“criteria_value
”字段。如果匹配,则可以显示此行的banner_id
。UserDefined
:这将告诉横幅控件在“BMS_BANNER_DISPLAY_CRITERIAS
”表中查找“criteria_code
”等于“UserDefined
”的记录,并将其与控件的“UserDefinedParameterValue
”属性中用户输入的值与“criteria_value
”字段进行比较。如果匹配,则可以显示此行的banner_id
。
在这种情况下,我们想在页面顶部有一个横幅区域(468 X 60 像素),如果此区域还没有添加任何横幅,则显示“广告位”图片。否则,它将显示横幅并根据每个横幅指定的显示时间(以秒为单位)进行轮播。
BannerRotator
控件代码将是
<BMS:BannerRotator runat="server" ID="banner1"
ConnectionString="<%$ ConnectionStrings:bms_db %>"
BannersLanguage="en" LocationCode="TOP"
BannerImagesURL="<%$ appSettings:bms_data %>"
BannerClickFile="~/click.aspx" ScriptsPath="/scripts/"
ShowOnlyActivatedBanners="true" Repeat="NoRepeat" />
根据控件中设置的属性,控件将读取上述记录,并且由于“Repeat
”属性设置为“NoRepeat
”,它将按“ls_order
”字段升序选择顶部记录。横幅显示的其结果将如下所示:
由于在此记录下“BMS_BANNERS”表中还没有添加任何横幅,并且“NoAds_image
”字段不为 null,这将指示横幅保留该区域并显示该字段中指定的图片。
我们在“BMS_BANNERS”表中为此记录添加横幅记录,如下图所示:
根据上述记录图像,横幅轮播控件将开始显示横幅,并根据列表顺序“ls_order
”进行轮播。
在这种情况下,我们想在页面左侧显示四个大小相等的横幅(202 X 96 像素),并垂直排列。它们不可点击。
首先,在“BMS_BANNERS_AREAS”表中添加四条记录,如下所示:
然后,像下面这样在您的 ASPX 页面中添加代码:
<BMS:BannerRotator runat="server" ID="BannerRotator1"
ConnectionString="<%$ ConnectionStrings:bms_db %>"
BannersLanguage="en" LocationCode="LFT"
ScriptsPath="/scripts/" BannerImagesURL="<%$ appSettings:bms_data %>"
Repeat="RepeatY" VerticalSpacing="5"
ShowOnlyActivatedBanners="true"/>
上面的代码将读取所有 location_code="LFT"
和 lang="en"
的记录,并按“ls_order
”排序,因为“Repeat
”属性设置为“RepeatY
”(垂直列表)。由于所有记录在“NoAds_image
”字段中都为 null,因此不会保留任何横幅区域。它只会显示该区域中添加的横幅(如果存在)。
我们为上面的每个横幅区域在“BMS_BANNERS”表中添加一条横幅记录:
根据上述记录,横幅控件的结果将是这样的:
我将“VerticalSpacing
”属性设置为“5”。
在这种情况下,我们想在页面右侧显示三个不同大小的横幅区域。前两个横幅区域的尺寸为 157 X 55 像素,第三个尺寸为 157 X 264 像素。我们想垂直排列它们。如果还没有添加任何横幅,它们都应该显示“广告位”图片。
代码将是
<BMS:BannerRotator runat="server" ID="BannerRotator2"
ConnectionString="<%$ ConnectionStrings:bms_db %>"
BannerImagesURL="<%$ appSettings:bms_data %>"
BannersLanguage="en" LocationCode="RGT"
Repeat="RepeatY" VerticalSpacing="5"
ShowOnlyActivatedBanners="true"
BorderWidth="1" BorderColor="Red"
BorderStyle="Solid" BannerClickFile="~/click.aspx" />
根据记录,横幅控件将显示三个横幅区域,带有“广告位”图片。因为它们所有的“NoAds_image
”字段都不为 null,而且它们都还没有添加横幅,所以结果将是这样的:
我们在第一个横幅区域下添加了两个“BMS_BANNERS”表记录:
根据上面的记录图像,横幅轮播控件将开始显示横幅,并根据列表顺序“ls_order”(第一个横幅区域)进行轮播。
在这种情况下,我们将采用第一个场景并添加一些高级功能。我们想根据“PageURL
”、“QueryString
”、“Session
”、“Cookies
”和“UserDefined
”来控制横幅的显示。
正如我上面提到的,顶部的横幅区域有三个横幅:banner_id=14、banner_id=15 和 banner_id=16。我们只想在页面 URL 是“/BannerRotator_test/default.aspx”时或当我们有查询字符串“q=1”时显示 banner_id=14。
ASP.NET 代码
<BMS:BannerRotator BannersLanguage="en" ConnectionString="<%$
ConnectionStrings:bms_db %>" LocationCode="TOP"
ScriptsPath="/scripts/" runat="server" ID="banner1"
BannerImagesURL="<%$ appSettings:bms_data %>"
BannerClickFile="~/click.aspx"
ShowOnlyActivatedBanners="true" Repeat="NoRepeat" >
<BMS:BannerDisplayCheck ParameterType="PageURL" />
<BMS:BannerDisplayCheck ParameterType="QueryString" ParameterName="q" />
<BMS:BannerDisplayCheck ParameterType="Session" ParameterName="my_session" />
<BMS:BannerDisplayCheck ParameterType="Cookie" ParameterName="my_cookie" />
<BMS:BannerDisplayCheck ParameterType="UserDefined" />
</BMS:BannerRotator>
“BannerDisplayCheck
”参数将告诉横幅轮播在“BMS_BANNER_DISPLAY_CRITERIAS”表中查找并根据匹配的标准比较值并显示横幅。以下是参数类型和用法:
类库
该控件的想法是从数据库获取横幅,并根据每个横幅指定的显示时间进行轮播。最初,我利用 AJAX 来完成这项工作。我使用了 AJAX 的 Timer
和 UpdatePanel
控件。我使用 timer 的 tick 事件来显示下一个横幅。但这是一个非常糟糕的方法,因为它占用了大量的服务器资源和带宽。UpdatePanel
最大的缺点是它仍然会将所有的 viewstate 来回发送,因此会消耗大量带宽。另一个缺点是大多数页面生命周期仍然会运行。
我继续使用 AJAX 和 Web Services 来提高性能并减少带宽使用,返回 JSON 数据,并在浏览器中使用 JavaScript 来构建 HTML 并将其注入页面。这提高了性能,但我并不满意,因为每次 timer tick 事件,我都必须从数据库读取下一个横幅记录。
最后,我提出了这个控件,它一次性从数据库读取所有横幅,并生成 HTML 和 JavaScript 来在客户端进行轮播,使用 JavaScript 函数“setTimeout
”。这是在控件的“RenderContents
”事件中完成的。下面是一个生成的横幅轮播代码示例:
<div id="Banner115"></div>
<script type="text/javascript">
var BannerHtml_arr15= new Array();
var swfId_arr15 = new Array();
var DisplayTimeSeconds_arr15 = new Array();
var banner_count15 =0;
var BannerHtml15=null;
var swfId15=null;
var BannerIndex15=0;
banner_count15=3
//array items generated from the database
BannerHtml_arr15[0]="<a href='https://codeproject.org.cn/BannerRotator" +
"_test/click.aspx?clickid=6418cd46-791a-40e1-9c11-e3e732977" +
"dc2452¶ms=PageURL%7c%2fBannerRotator_test%2fDefault" +
".aspx' target='_blank' title='Eztrade.bh'><img" +
" src='https:///biznet-data/bms_test/en/banners/" +
"BCCI_en_ad_eztrade468X60.jpg' style='border:Solid " +
"0px black;' width='468' height='60'></a>";
swfId_arr15[0]='';
DisplayTimeSeconds_arr15[0]='3000';
BannerHtml_arr15[1]="<img src='https:///biznet-data/" +
"bms_test/en/banners/bcci_en_shops_eztrade.gif' style='border:" +
"Solid 0px black;' width='468' height='60' title='Eztrade Shops'>";
swfId_arr15[1]='';
DisplayTimeSeconds_arr15[1]='2000';
BannerHtml_arr15[2]="";
swfId_arr15[2]='https:///biznet-data/bms_test/en/banners/bcci_en_banner1';
DisplayTimeSeconds_arr15[2]='7000';
function DisplayBanner15()
{
if (BannerHtml15!=null || swfId15!=null)
{
if (BannerHtml15!=null) {
document.getElementById('Banner115').innerHTML =BannerHtml15;
}
else if (swfId15!=null) {
//loading flash object using java script.
var lcId15 = new Date().getTime();
var flashProxy15 = new FlashProxy(lcId15,
'/BannerRotator_test/scripts/JavaScriptFlashGateway.js');
var flashObject15 = new FlashTag(swfId15+'.swf',468,60, '8,0,0,0');
flashObject15.setFlashvars('lcId=' + lcId15);
flashObject15.write(document.getElementById('Banner115'));
}
}
if (banner_count15>1)
setTimeout('DisplayBanner15()',
DisplayTimeSeconds_arr15[BannerIndex15],'JavaScript')
BannerIndex15++;
if (BannerIndex15 >= banner_count15)
BannerIndex15=0;
SetValues15();
}
function SetValues15()
{
if (BannerHtml_arr15[BannerIndex15]!=null && BannerHtml_arr15[BannerIndex15]!='')
BannerHtml15 = BannerHtml_arr15[BannerIndex15];
else
BannerHtml15 = null;
if (swfId_arr15[BannerIndex15]!=null && swfId_arr15[BannerIndex15]!='')
swfId15 = swfId_arr15[BannerIndex15];
else
swfId15 = null;
}
function LoadBanners15()
{
if (BannerIndex15==0)
{
SetValues15();
DisplayBanner15();
}
}
LoadBanners15();
</script>
在我开始之前,这是横幅控件数据库的屏幕截图:
代码是从控件的“RenderContents
”事件调用的。最初,我们通过调用以下函数获取横幅区域列表:
protected DataTable GetBannerArea()
{
DataTable retVal = null;
string sql = "select ";
//selecting a single record (first record based on order of "ls_order" column)
if (_Repeat == RepeatOptions.NoRepeat)
sql += "top 1 ";
sql += " * from BMS_BANNERS_AREAS where location_code=@location_code" +
" and lang=@lang and Active_flag='1' order by ls_order";
SqlConnection conn = new SqlConnection(_ConnectionString);
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
try
{
da.SelectCommand.Parameters.AddWithValue("location_code", _LocationCode);
da.SelectCommand.Parameters.AddWithValue("lang", _lang);
DataTable dt = new DataTable();
if (_EnableCaching)
{
DataTable dt_c = HttpContext.Current.Cache["AdRotator_" +
_Repeat.ToString() + "_" +
_LocationCode + "_" + _lang] as DataTable;
if (dt_c != null)
dt = dt_c;
else
{
da.Fill(dt);
HttpContext.Current.Cache.Insert("AdRotator_" +
_Repeat.ToString() + "_" + _LocationCode + "_" +
_lang, dt, null,
DateTime.Now.AddMinutes(_CacheDuration), TimeSpan.Zero);
}
}
else
da.Fill(dt);
da.Dispose();
conn.Dispose();
retVal = dt;
}
catch (Exception ex)
{
throw new Exception("Exception Accured in : protected" +
" void GetBannerArea(). For More Details " +
"See Inner Exception Message", ex);
}
return retVal;
}
上述函数将根据“Location_code
”和“Lang
”从“BMS_BANNERS_AREAS”表中检索横幅区域。每行将定义一个具有尺寸的横幅区域。我调用该函数来获取包含结果的 DataTable
。
//initially we get the list of banner areas in a datatable
DataTable dt_banner_areas = GetBannerArea();
然后,我循环遍历记录以生成 HTML 和 JavaScript 代码。请参阅上面生成的示例。
//loop through the banner areas
foreach (DataRow dr in dt_banner_areas.Rows)
{
// assigning values
_banner_area_id = Convert.ToString(dr["banner_area_id"]);
_Width = Convert.ToString(dr["widthpx"]);
_Height = Convert.ToString(dr["hieghtpx"]);
if (!string.IsNullOrEmpty(Convert.ToString(dr["NoAds_image"])))
_NoAdFile = string.Format(_bms_data_url, _lang) +
Convert.ToString(dr["NoAds_image"]);
_NoAdAlt = Convert.ToString(dr["NoAds_imageAlt"]);
//again check the banner areas count for doing
//the html table. and placing the banner areas.
if (dt_banner_areas.Rows.Count > 1)
{
if (_Repeat == RepeatOptions.RepeatX)
sb.Append("" + Environment.NewLine);
else if (_Repeat == RepeatOptions.RepeatY)
sb.Append("" + Environment.NewLine);
}
//start doing the html and javascript. better you view source
//of the aspx page to see the resulted html.
sb.Append(@"<div id=""Banner1" +
_banner_area_id + @""">" + Environment.NewLine);
sb.Append("</div>" + Environment.NewLine);
//writing up the javasctript that will do the banner rotation.
sb.Append(@"<script type=""text/javascript"">" +
Environment.NewLine);
sb.Append(@"var BannerHtml_arr" + _banner_area_id +
"= new Array();" + Environment.NewLine);
sb.Append(@"var swfId_arr" + _banner_area_id +
" = new Array();" + Environment.NewLine);
sb.Append(@"var DisplayTimeSeconds_arr" + _banner_area_id +
" = new Array();" + Environment.NewLine);
sb.Append(@"var banner_count" + _banner_area_id +
" =0;" + Environment.NewLine);
sb.Append(@"var BannerHtml" + _banner_area_id +
"=null;" + Environment.NewLine);
sb.Append(@"var swfId" + _banner_area_id +
"=null;" + Environment.NewLine);
sb.Append(@"var BannerIndex" + _banner_area_id +
"=0;" + Environment.NewLine);
// getting the generated javascript array list
sb.Append(GenerateJavascriptArrayItems());
sb.Append(@"function DisplayBanner" +
_banner_area_id + "()" + Environment.NewLine);
sb.Append(@"{" + Environment.NewLine);
// sb.Append(@"// alert(swfId" + _banner_area_id + ");" + Environment.NewLine);
sb.Append(@"if (BannerHtml" + _banner_area_id +
"!=null || swfId" + _banner_area_id +
"!=null)" + Environment.NewLine);
sb.Append(@"{" + Environment.NewLine);
sb.Append(@"if (BannerHtml" + _banner_area_id + "!=null) {" + Environment.NewLine);
sb.Append(@"document.getElementById('Banner1" +
_banner_area_id + "').innerHTML =BannerHtml" +
_banner_area_id + ";" + Environment.NewLine);
sb.Append(@"}" + Environment.NewLine);
sb.Append(@"else if (swfId" + _banner_area_id + "!=null) {" + Environment.NewLine);
sb.Append(@"//loading flash object using java script." + Environment.NewLine);
sb.Append(@"var lcId" + _banner_area_id +
" = new Date().getTime();" + Environment.NewLine);
sb.Append(@"var flashProxy" + _banner_area_id +
" = new FlashProxy(lcId" + _banner_area_id + ", '" +
VirtualPathUtility.ToAbsolute("~" + _JavaScriptFlashGateway_path +
"JavaScriptFlashGateway.js") + "');" + Environment.NewLine);
sb.Append(@"var flashObject" + _banner_area_id +
" = new FlashTag(swfId" + _banner_area_id +
"+'.swf'," + _Width + "," + _Height +
", '8,0,0,0');" + Environment.NewLine);
sb.Append(@"flashObject" + _banner_area_id +
".setFlashvars('lcId=' + lcId" + _banner_area_id +
");" + Environment.NewLine);
sb.Append(@"flashObject" + _banner_area_id +
".write(document.getElementById('Banner1" +
_banner_area_id + "'));" + Environment.NewLine);
sb.Append(@"}" + Environment.NewLine);
sb.Append(@"}" + Environment.NewLine);
sb.Append(@"if (banner_count" + _banner_area_id + ">1)" + Environment.NewLine);
sb.Append(@"setTimeout('DisplayBanner" + _banner_area_id +
"()',DisplayTimeSeconds_arr" + _banner_area_id +
"[BannerIndex" + _banner_area_id +
"],'JavaScript')" + Environment.NewLine);
sb.Append(@"BannerIndex" + _banner_area_id + "++;" + Environment.NewLine);
sb.Append(@"if (BannerIndex" + _banner_area_id +
" >= banner_count" + _banner_area_id +
")" + Environment.NewLine);
sb.Append(@"BannerIndex" + _banner_area_id + "=0;" + Environment.NewLine);
sb.Append(@"SetValues" + _banner_area_id + "();" + Environment.NewLine);
sb.Append(@"}" + Environment.NewLine);
sb.Append(@"function SetValues" + _banner_area_id + "()" + Environment.NewLine);
sb.Append(@"{" + Environment.NewLine);
sb.Append(@"if (BannerHtml_arr" + _banner_area_id +
"[BannerIndex" + _banner_area_id +
"]!=null && BannerHtml_arr" + _banner_area_id +
"[BannerIndex" + _banner_area_id + "]!='')" + Environment.NewLine);
sb.Append(@"BannerHtml" + _banner_area_id +
" = BannerHtml_arr" + _banner_area_id +
"[BannerIndex" + _banner_area_id +
"];" + Environment.NewLine);
sb.Append(@"else" + Environment.NewLine);
sb.Append(@"BannerHtml" + _banner_area_id + " = null;" + Environment.NewLine);
sb.Append(@"if (swfId_arr" + _banner_area_id +
"[BannerIndex" + _banner_area_id +
"]!=null && swfId_arr" + _banner_area_id +
"[BannerIndex" + _banner_area_id + "]!='')" + Environment.NewLine);
sb.Append(@"swfId" + _banner_area_id + " = swfId_arr" +
_banner_area_id + "[BannerIndex" +
_banner_area_id + "];" + Environment.NewLine);
sb.Append(@"else" + Environment.NewLine);
sb.Append(@"swfId" + _banner_area_id + " = null;" + Environment.NewLine);
sb.Append(@"}" + Environment.NewLine);
sb.Append(@"function LoadBanners" +
_banner_area_id + "()" + Environment.NewLine);
sb.Append(@"{" + Environment.NewLine);
sb.Append(@"if (BannerIndex" + _banner_area_id + "==0)" + Environment.NewLine);
sb.Append(@"{" + Environment.NewLine);
sb.Append(@"SetValues" + _banner_area_id + "();" + Environment.NewLine);
sb.Append(@"DisplayBanner" + _banner_area_id + "();" + Environment.NewLine);
sb.Append(@"}" + Environment.NewLine);
sb.Append(@"}" + Environment.NewLine);
sb.Append(@"LoadBanners" + _banner_area_id + "();" + Environment.NewLine);
sb.Append(@"</script>" + Environment.NewLine);
}
注意,我调用函数“GenerateJavascriptArrayItems
”来生成 JavaScript 的数组项。此函数会获取添加到特定横幅区域下的所有横幅记录。
protected string GenerateJavascriptArrayItems()
{
string retVal = null;
// getting list of banner within an area banner.
// based on the "_banner_area_id"
DataTable dt = GetBannersWithinArea();
int i = 0;
if (dt.Rows.Count > 0)
{
retVal += "banner_count" + _banner_area_id + "=" +
dt.Rows.Count.ToString() +
Environment.NewLine + Environment.NewLine;
//loop through the banners
foreach (DataRow dr in dt.Rows)
{
//generate the banner
GenerateBannerHTML(dr);
retVal += "BannerHtml_arr" + _banner_area_id +
"[" + i.ToString() + "]=\"" +
_BannerHtml + "\";" + Environment.NewLine;
retVal += "swfId_arr" + _banner_area_id + "[" +
i.ToString() + "]='" + _swfId +
"';" + Environment.NewLine;
retVal += "DisplayTimeSeconds_arr" + _banner_area_id +
"[" + i.ToString() + "]='" +
_DisplayTimeSeconds + "';" +
Environment.NewLine + Environment.NewLine;
i++;
//nullfy the values for next banner usage
_BannerHtml = null;
_swfId = null;
_DisplayTimeSeconds = 0;
}
}
else
{
//generate and empty banner. (just the banner area block
//with advertizing space image if provided)
GenerateBannerHTML(null);
retVal += "BannerHtml_arr" + _banner_area_id + "[0]=\"" +
_BannerHtml + "\";" + Environment.NewLine;
retVal += "swfId_arr" + _banner_area_id + "[0]='" +
_swfId + "';" + Environment.NewLine;
retVal += "DisplayTimeSeconds_arr" + _banner_area_id +
"[0]='" + _DisplayTimeSeconds + "';" +
Environment.NewLine + Environment.NewLine;
}
return retVal;
}
在上述函数中,我调用另一个函数“GetBannersWithinArea
”来获取特定横幅区域的横幅,然后循环遍历记录以生成 JavaScript 数组项。我调用另一个函数“GenerateBannerHTML
”。此函数会将 HTML 标记赋值给变量“_BannerHtml
”。
protected DataTable GetBannersWithinArea()
{
DataTable retVal = null;
//generating sql statement for selecting the banners
string sql = "select * from BMS_BANNERS";
sql += " where banner_area_id=" + _banner_area_id;
//check for banner start date and expiry date
sql += " and CONVERT(varchar(10),expiry_date,121) " +
">=CONVERT(varchar(10),getdate(),121) ";
sql += " and CONVERT(varchar(10),getdate(),121) " +
">=CONVERT(varchar(10),start_date,121) ";
//apply banner display condition based
//on the user define parameters in the control.
string BannerDisplaySqlConditions = GetBannerDisplaySqlConditions();
if (!string.IsNullOrEmpty(BannerDisplaySqlConditions))
sql += BannerDisplaySqlConditions;
if (_ShowOnlyActivatedBanners)
sql += " and active_flag='1' ";
sql += " order by ls_order";
SqlConnection conn = new SqlConnection(_ConnectionString);
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
DataTable dt = new DataTable();
try
{
//applying cache if applicable.
if (_EnableCaching)
{
string c_BannerDisplaySqlConditions = null;
if (!string.IsNullOrEmpty(BannerDisplaySqlConditions))
{
c_BannerDisplaySqlConditions = BannerDisplaySqlConditions.Replace(" ", "_");
c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace("'", "_");
c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace(">", "_");
c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace("<", "_");
c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace("(", "_");
c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace(")", "_");
c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace(":", "_");
c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace("/", "_");
c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace(@"\", "_");
c_BannerDisplaySqlConditions = c_BannerDisplaySqlConditions.Replace("=", "_");
}
//get data from cache if exists
DataTable dt_c = HttpContext.Current.Cache["AdRotator_" + _banner_area_id +
"_" + _ShowOnlyActivatedBanners + "_" +
c_BannerDisplaySqlConditions] as DataTable;
if (dt_c != null)
dt = dt_c;
else
{
//or get it from database and store it in the cache for later retrieval.
da.Fill(dt);
HttpContext.Current.Cache.Insert("AdRotator_" + _banner_area_id +
"_" + _ShowOnlyActivatedBanners + "_" +
c_BannerDisplaySqlConditions, dt, null,
DateTime.Now.AddMinutes(_CacheDuration), TimeSpan.Zero);
}
}
else
da.Fill(dt);
da.Dispose();
retVal = dt;
}
catch (Exception ex)
{
throw ex;
}
finally
{
conn.Dispose();
}
return retVal;
}
上述函数将根据“banner_area_id
”从表“BMS_BANNERS”检索横幅记录。
我还想提一下,我已经实现了一个属性集合。这些是“BannerDisplayCheck
”参数,我在上面“有条件地在横幅区域中显示横幅”标题下提到了它们。
为此,我创建了一个单独的类 BannerDisplayCheck
。
using System;
using System.Collections;
using System.ComponentModel;
using System.Web.UI;
namespace BannerRotatorControl
{
[TypeConverter(typeof(ExpandableObjectConverter))]
public class BannerDisplayCheck
{
public enum CriteriaTypes
{
PageURL, QueryString, Session, Cookie, UserDefined
}
protected CriteriaTypes _criteraType = CriteriaTypes.PageURL;
protected string _CriteriaName = null;
public BannerDisplayCheck()
: this(CriteriaTypes.PageURL, string.Empty)
{
}
public BannerDisplayCheck(CriteriaTypes CriteriaType, string Name)
{
_criteraType = CriteriaType;
_CriteriaName = Name;
}
[
Category("Behavior"),
DefaultValue(""),
Description("List of Different types of parameters: " +
"PageURL, QuertString, Session, Cookie"),
NotifyParentProperty(true),
]
public CriteriaTypes ParameterType
{
get
{
return _criteraType;
}
set
{
_criteraType = value;
}
}
[
Category("Behavior"),
DefaultValue(""),
Description("ParameterName: exmaple: Name " +
"of the QueryString, Session,Coookie"),
NotifyParentProperty(true)
]
public string ParameterName
{
get
{
return _CriteriaName;
}
set
{
_CriteriaName = value;
}
}
}
}
然后在我的主类“BannerRotator
”中,我实现了“INamingContainer
”接口:
//[DefaultProperty("Text")]
[ParseChildren(true, "BannerDisplayCheckCollection")]
[PersistChildren(false)]
[ToolboxData("<{0}:BannerRotator runat="server">")]
public class BannerRotator : WebControl, INamingContainer
然后下面的公共属性将负责收集用户的属性信息:
[
Category("Behavior"),
Description("The BannerDisplayCheck collection"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty),
DefaultValue(null), MergableProperty(false), Bindable(false)
]
public List<BannerDisplayCheck> BannerDisplayCheckCollection
{
get
{
if (_BannerDisplayCheck == null)
{
_BannerDisplayCheck = new List<BannerDisplayCheck>();
}
return _BannerDisplayCheck;
}
}
我在函数“GetBannerDisplaySqlConditions
”中使用该集合。此函数将构建函数“GetBannersWithinArea
”中 SQL 语句的查找部分。
protected string GetBannerDisplaySqlConditions()
{
string retVal = null;
if (_BannerDisplayCheck.Count > 0)
{
retVal += " and banner_id in (select banner_id " +
"from BMS_BANNER_DISPLAY_CRITERIAS where ";
foreach (BannerDisplayCheck bdc in _BannerDisplayCheck)
{
switch (bdc.ParameterType)
{
case BannerDisplayCheck.CriteriaTypes.QueryString:
if (!string.IsNullOrEmpty(
HttpContext.Current.Request[bdc.ParameterName]))
{
retVal += "(criteria_code='" +
bdc.ParameterType.ToString() + "'";
retVal += " and criteria_value='" +
HttpContext.Current.Request[bdc.ParameterName] +
"') or ";
}
break;
case BannerDisplayCheck.CriteriaTypes.PageURL:
retVal += "(criteria_code='" +
bdc.ParameterType.ToString() + "'";
retVal += " and criteria_value='" +
HttpContext.Current.Request.RawUrl.Split('?')[0] +
"') or ";
break;
case BannerDisplayCheck.CriteriaTypes.UserDefined:
if (!string.IsNullOrEmpty(_UserDefinedParameterValue))
{
retVal += "(criteria_code='" +
bdc.ParameterType.ToString() + "'";
retVal += " and criteria_value='" +
_UserDefinedParameterValue + "') or ";
}
break;
case BannerDisplayCheck.CriteriaTypes.Session:
if (!string.IsNullOrEmpty(Convert.ToString(
HttpContext.Current.Session[bdc.ParameterName])))
{
retVal += "(criteria_code='" +
bdc.ParameterType.ToString() + "'";
retVal += " and criteria_value='" +
HttpContext.Current.Session[
bdc.ParameterName].ToString() +
"') or ";
}
break;
case BannerDisplayCheck.CriteriaTypes.Cookie:
HttpCookie cookies =
HttpContext.Current.Request.Cookies[bdc.ParameterName];
if (cookies != null)
{
if (!string.IsNullOrEmpty(Convert.ToString(
HttpContext.Current.Request.Cookies[bdc.ParameterName].Value)))
{
retVal += "(criteria_code='" +
bdc.ParameterType.ToString() + "'";
retVal += " and criteria_value='" +
HttpContext.Current.Request.Cookies[
bdc.ParameterName].Value.ToString() +
"') or ";
}
}
break;
default:
break;
}
}
//removing the last un-needed or
retVal = retVal.Substring(0, retVal.Length - 3);
retVal += ")";
}
#if (debug)
HttpContext.Current.Response.Write(retVal);
// HttpContext.Current.Response.End();
#endif
return retVal;
}
结论
有关源代码的更多详细信息,请从本文顶部下载源代码。源代码易于理解且注释良好。下载演示以查看使用该控件的不同场景。
希望此控件有用,我希望看到评论和投票。