65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (16投票s)

2010年1月7日

CPOL

11分钟阅读

viewsIcon

51921

downloadIcon

2808

一个数据库驱动的横幅轮播控件,它基于特定的时间进行旋转(而不是在页面刷新时)。每个横幅都有一个显示时间(以秒为单位)来切换到下一个。

引言

在本文中,我想介绍我的横幅轮播控件。它的构思与 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"   %>
  • 像这样在您的 ASPX 页面中使用它
  • <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.mdfbms_db.ldf 包含在源代码中。)
  • BannersLanguageLocationCode:这些是必填属性。它们是主要属性,它们告诉 BannerRotator 根据以下表从数据库读取数据
  • 03.jpg

    BMS_BANNERS_AREAS 包含横幅区域列表。在上述 ASP.NET 控件中,我设置了 BannersLanguage="en" LocationCode="TOP",这会告诉控件读取 lang="en"location_code="TOP"(高亮显示的那一行)的横幅区域记录,并根据这些记录字段中指定的信息绘制横幅区域。

    • Widthpx
    • Heightpx
    • NoAds_image:这将控制即使该区域没有横幅,也要保留横幅区域。

    01.jpg

    语言主表

    02.jpg

    包含位置列表的主表(位置是指页面位置 - 左、右、顶部和底部)
  • BannerImagesURL:此属性告诉控件横幅图片文件的位置 URL。我已将上面的属性设置为从 web.configappSettings 键读取。
  • <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 脚本路径。
  • 04.jpg

  • ShowOnlyActivatedBanners:如果只想显示已激活的横幅,请将其设置为 true;否则设置为 false 以显示所有横幅(如果您在 Banner Management Admin 网站中使用横幅轮播,请将其设置为 false)。

使用 BannerRotator 控件的不同方法

我们可以在不同的场景中使用该控件;我将列出最常见的几种:

  1. 单个预留横幅区域轮播多个横幅
  2. 在这种情况下,我们想在页面顶部有一个横幅区域(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"  />

    06.jpg

    根据控件中设置的属性,控件将读取上述记录,并且由于“Repeat”属性设置为“NoRepeat”,它将按“ls_order”字段升序选择顶部记录。横幅显示的其结果将如下所示:

    bcci_en_noad468X60.jpg

    由于在此记录下“BMS_BANNERS”表中还没有添加任何横幅,并且“NoAds_image”字段不为 null,这将指示横幅保留该区域并显示该字段中指定的图片。

    我们在“BMS_BANNERS”表中为此记录添加横幅记录,如下图所示:

    07.jpg

    根据上述记录图像,横幅轮播控件将开始显示横幅,并根据列表顺序“ls_order”进行轮播。

    • 将显示第一个横幅“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 秒。
    • 然后它将再次循环。
  3. 多个横幅区域,每个区域只有一个横幅
  4. 在这种情况下,我们想在页面左侧显示四个大小相等的横幅(202 X 96 像素),并垂直排列。它们不可点击。

    首先,在“BMS_BANNERS_AREAS”表中添加四条记录,如下所示:

    08.jpg

    然后,像下面这样在您的 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”表中添加一条横幅记录:

    09.jpg

    根据上述记录,横幅控件的结果将是这样的:

    10.jpg

    我将“VerticalSpacing”属性设置为“5”。

  5. 多个预留横幅区域,多个横幅
  6. 在这种情况下,我们想在页面右侧显示三个不同大小的横幅区域。前两个横幅区域的尺寸为 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" />

    11.jpg

    根据记录,横幅控件将显示三个横幅区域,带有“广告位”图片。因为它们所有的“NoAds_image”字段都不为 null,而且它们都还没有添加横幅,所以结果将是这样的:

    12.jpg

    我们在第一个横幅区域下添加了两个“BMS_BANNERS”表记录:

    13.jpg

    根据上面的记录图像,横幅轮播控件将开始显示横幅,并根据列表顺序“ls_order”(第一个横幅区域)进行轮播。

    • 第一个显示的横幅是“bcci_en_btn.jpg”,持续 4 秒,并且由于“link_url”设置为“http://www.bahraintradanet.com/”,因此它是可点击的。
    • 第二个横幅是“bcci_en_gtn.jpg”,持续 6 秒,并且由于“link_url”设置为“http://www.gulftradanet.com/”,因此它是可点击的。
    • 然后它将再次循环。
  7. 有条件地在横幅区域中显示横幅
  8. 在这种情况下,我们将采用第一个场景并添加一些高级功能。我们想根据“PageURL”、“QueryString”、“Session”、“Cookies”和“UserDefined”来控制横幅的显示。

    正如我上面提到的,顶部的横幅区域有三个横幅:banner_id=14、banner_id=15 和 banner_id=16。我们只想在页面 URL 是“/BannerRotator_test/default.aspx”时或当我们有查询字符串“q=1”时显示 banner_id=14。

    14.jpg

    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”表中查找并根据匹配的标准比较值并显示横幅。以下是参数类型和用法:

    • 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

类库

该控件的想法是从数据库获取横幅,并根据每个横幅指定的显示时间进行轮播。最初,我利用 AJAX 来完成这项工作。我使用了 AJAX 的 TimerUpdatePanel 控件。我使用 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>

在我开始之前,这是横幅控件数据库的屏幕截图:

05.jpg

代码是从控件的“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;
}

结论

有关源代码的更多详细信息,请从本文顶部下载源代码。源代码易于理解且注释良好。下载演示以查看使用该控件的不同场景。

希望此控件有用,我希望看到评论和投票。

© . All rights reserved.