ASP.NET网站制作之天生 ContentRotator ASP.NET 服务器控...
J2EE比较成熟一点,一些比较出名的企业应用软件都是基于J2EE的。以后的发展就不好说了。不过java比较烦,学.net的话,微软把很多工具都封装好了,学起来可能容易一点。asp.net|服务器|控件 择要:先容创立自界说、编译的ASP.NET服务器控件触及的步骤,这类控件对一切的特定内容举行随机转动,就像内置的AdRotator控件随机转动一系列预界说的口号告白一样。在先容ContentRotator控件的中心内容时,本文触及到自界说ASP.NET控件开辟的几个方面。
简介
早在九十年月末期,仿佛没有甚么事变是不成能产生的。WorldWideWeb及其对贸易的影响急剧增添―孩子们入学创建Web站点而一夜暴富,企业也斥资数百万美圆在黄金电视时段播放告白,吸惹人们上彀为宠物购置食品。没错,这就是新经济时期,比拟于在使人有趣的修建物中发卖单调的旧产物而言,将数百万的Web网平易近吸引到Web站点来切实其实更有经济代价。
在这个浮华的时期,Microsoft引进了传统ASP的AdRotatorCOM组件,它使崭露锋芒的Web企业家可以将口号告白轻松增加到他们的站点中。显现口号告白的第一步是具有一个列出能够显现的口号的advertisements文件。该文本文件包括有关每一个口号的四类信息:
•指向该口号图象的URL
•该图象链接到的URL
•该图象的交换文本
•该口号相对文件中其他口号的显现频次
利用该文本文件时,ASP开辟职员必须挪用AdRotator的GetAdvertisement(advertisementFile)办法,从而传进到advertisements文件的路径,而AdRotator将前往HTML标志,用于显现从指定文件随机选择的口号告白。我想,这时候候已财路滔滔了。
2002年托付ASP.NET时,新经济时期已成为已往。NASDAQ指数在2000年已经爬升至5,000点摆布,而如今已跌到2,000点以下。只管.com完全倒台,但Microsoft仍旧对在线告白持悲观立场,启事是他们已修整了传统ASP的AdRotator控件并举行了公布―作为一个尺度Web控件与ASP.NET一同供应。AdRotator的ASP.NET版本较之传统的ASP版本有以下几个上风:
•advertisements文件现已经是XML格局化的,从而使页面开辟职员能够更轻松地创立和编纂该文件的内容。
•每一个告白能够包括一个唆使其所属种别的关头字。除AdRotator的新KeywordFilter属性以外,这可用来限定针对详细AdRotator控件实例显现的口号集。
•除尺度的告白属性集以外,页面开辟职员能够将他们本人的附加设置增加到advertisements文件中。然后,增加的这些设置可由页面开辟职员经由过程AdRotator的AdCreated事务以编程体例会见。
固然AdRotator能更简单地随机显现来自预界说列表的口号,可是它存在良多弱点,在我看来,个中有两个次要的弱点:
1.AdRotator的内容只能够经由过程XML格局化的advertisements文件举行指定。这固然不是一个次要限定,可是假如可以经由过程AdRotator的标志以声明体例指定内容,大概经由过程源代码以编程体例举行指定,则是对照幻想的,这十分相似于针对DropDownListWeb控件以声明体例或编程体例指定ListItem。
2.AdRotator在它能够天生的标志方面遭到一些限定。望文生义,它旨在显现告白,这些告白是文本或链接到某个URL的图象。只需举行大批事情,就能够将AdRotator创立为显现任何范例的内容,而不单单是口号或文本告白。
第二个弱点出格让我感应懊恼,由于只需再举行大批事情就能够使AdRotator成为一个十分通用的内容转动器,而不单单计划为只显现告白。在本文中,我们将经由过程创立一个全功效的ContentRotator服务器控件来克制该弱点和其他弱点。
思索内容转动
在深切研讨任何编码项目之前,主要的是用充分的工夫回覆以下三个成绩。
1.有满意我必要的现有控件吗?假如您的事情和我相似,就是说天天有良多集会和电子邮件,还要消费更多工夫举行其他忙碌的事情,则编写代码一般是一天中最风趣的举动。假如对成绩发生了乐趣并经由过程代码找到该成绩的办理计划,那末没有甚么比这让使人镇静了。
可是,“风趣”与“具有经济代价”可完整是两回事。创立详细控件多是风趣的,但假如已存在可以供应所需功效的控件,那末消费工夫天生、测试和调剂此类控件就毫无经济意义可言。
当我想创立新的服务器控件时,我起首会进进ASP.NETControlGallery,看看我是否是在做无勤奋。疾速检察ControlGallery,显现用于ContentRotators的一个完全种别。可是,这些内容转动器(比方,旧事或股票主动吸收器)的年夜多半都在单个页面转动一切的内容。
我发明有一个控件能够转动完全的诸如AdRotator控件(DuncanMackenzie的ContentRotator用户控件,胪陈于文章RotatingIsFun)的恣意静态HTML内容。固然Duncan的用户控件供应了AdRotator的基础功效且撑持恣意HTML内容,但我决意不利用他的办理计划,由于它其实不供应我必要的功效。(比方,Duncan的控件不同意为内容标志关头字。)
在搜刮过程当中,我没有找到满意必要的内容转动器。因而我决意本人创立。(哈哈!老板,集会请先等一下吧,我如今要即刻完成一个编程项目!)
2.我的控件必要供应甚么功效?假如您决意创立本人的控件,请不要当即深切到最风趣的部分―编码;相反,您必要在入手下手编码之前分明地懂得该控件必要具有哪些功效。断定控件请求的一个好办法是计划惯例用例,这些用例形貌终极用户(在本例中是页面开辟职员)将怎样利用您的控件。在天生服务器控件时,我起首要自问的几个成绩是:
•页面开辟职员将怎样利用该控件?
•他们必要该控件做甚么?
•语法应当怎样?
在经由一番深图远虑以后,我计划了以下四个用例:
Harry(一个很有出路的ASP.NET开辟职员)想加强其公司的Intranet,以便主页能够随机显现一个公司雇员的简历和照片。因为Harry的公司只要十多个雇员,因而他今朝喜好在一个文件中硬编码简历和照片,但但愿往后能够对其举行晋级,以便跟着公司的开展从数据库检索这些项。他的方针是让ContentRotator从该文件随机选择一个雇员,每次会见时在主页上显现有关该雇员的信息。
Jisun是BuyPetFoodOnline.com的一名开辟职员,这个网站是新启动的,关于它的风险投资可否获得报答都寄但愿于JohnQ身上。人人对在线购置Alpo很感乐趣。BuyPetFoodOnline.com上发卖的一切宠物食品品牌都在一个MicrosoftSQLServer数据库中保护。在该站点的主页上,Jisun想显现最滞销的10种宠物食品品牌列表,大概各种狗食列表或猫食列表。别的,她但愿每当狗食或猫食的内容组应时,最滞销的十个发卖品牌内容均匀显现两次。
Todd运转一个有关健身的Web站点,今朝已无数千名会员在该站点上注册,注册信息包含姓名、出身日期、体重和其他和安康相干的数据。在每页的底部,Jim想针对会见者的团体信息显现随机安康统计信息。比方,他想显现以下动静:[]、您已活了[]天、您的均匀脉搏是[],个中每个占位符均用特定于登任命户的值举行添补。
发展中的ASP.NET开辟职员Darren是一个XML的老手,他很忧虑在XML格局化的内容文件中指定内容项时会出错误。Darren十分熟习DropDownListWeb控件,常常利用DropDownList的形貌性语法指定ListItem。Darren也但愿可以以不异的体例为ContentRotator指定内容项。一样,他将可以以编程体例操纵ContentRotator的内容项,利用的语法相似于以编程体例利用DropDownList的ListItem所需的语法。
ContentRotator的功效就是从这些用例中发生的,这些用例在ContentRotator的完成中供应引导。
3.有代码重用的大概性吗?面向工具编程的一年夜优点是,能够轻松兼并和扩大现有功效。在创立新服务器控件时,极可能已存在供应相似功效的ASP.NET服务器控件。只扩大该现有服务器控件而不从头天生服务器控件大概吗?在现有控件基本长进行构建将节俭大批的编码和测试工夫。
在入手下手创立用于ContentRotator的代码时,我实行了使ContentRotator扩大现有ASP.NETAdRotator控件的大概性。AdRotator类包括了从告白文件读取项并随机选择一个得当项所需的办法和属性。我可以重用该类偏重写发送口号或文本告白的特定办法,从而将其变动为前往更多一样平常内容的办法吗?
我思索了该办法,但因为以下缘故原由决意不利用它。起首,AdRotator的很多办法都没有标志为virtual,这意味着它们不克不及重写。出格是,因为剖析advertisements文件的办法不是假造的,因而我的派生类将必需利用AdRotator的现有XML格局。这纷歧定会限定ContentRotator的功效(因为AdRotator能够增加恣意XML元素),但它仍旧会发生一些限定,由于它将利用advertisement文件的和元素。别的,AdRotator必要一个元素,它关于一样平常内容转动器来讲是一个没法承受的请求。
在经由审慎思索以后,我终极筹办入手下手编写代码―这是一个风趣的环节。鄙人文中,我将先容ContentRotator控件的一些更风趣的代码,这些代码不但能够展现该特定控件的外部事情,还供应一个示例,用于在创立的服务器控件中完成类似的功效。
指定内容项
ContentRotator控件供应三种用于指定内容项的体例:
1.经由过程XML格局的一个独自内容文件。
2.经由过程ContentRotator的声明性语法。
3.经由过程服务器端编程办法。
第一个选项利用一个内部文件供应对内容项更好的重用,由于单个内容文件能够经由过程单个Web站点中分歧页上的很多内容转动器利用。可是,偶然您大概想疾速创立复杂的ContentRotator控件,而不用懊恼于创立独自的内容文件。在这些情形下,您可使用第二个选项,并供应内容项来迭代经由过程该控件的声明性语法。最初一个选项同意您以编程体例指定内容项。假如必要静态选择大概的内容项,大概这些内容项存在于一个数据库或其他某个非静态存储中,则该选项是有效的。
经由过程内容文件指定内容
当在XML格局化内容文件中指定内容项时,必需针对详细的XML架构供应内容项。出格是,内容文件必需以元素开首,该元素包括每一个内容项的元素。每一个项有三个可选属性:
•impressions―指定内容项的主要性,用来断定项显现的几率。
•keyword―指定内容项的关头字。ContentRotator控件包括一个KeywordFilter属性,假如设置该属性,则将所显现的内容项限定为具有婚配的关头字参数的内容项。
•contentPath―内容项能够包括静态HTML标志或代码驱动的静态内容。假如您想利用静态内容,能够经由过程该属性指定到UserControl的路径。假如设置所选内容项的contentPath属性,则该内容经由过程指定的UserControl天生。
元素也能够包括供应要显现的静态标志的文本。假如未供应contentPath属性,则显现该静态标志。
以下示例显现一个带有四个内容项的、准确举行格局化的内容文件。第一个内容项短少任何可选属性,只由要显现的文本内容构成。第二个内容项供应impressions和keyword属性,而第三个内容项只设置keyword属性。请注重,假如您想在内容项的文本部分显现HTML标志,则必要像在第二个示例中一样本义XML标志,办法是利用<和>而不是<和>,大概必要将全部内容包装在一个部分中。第四个(最初一个)内容项援用一个UserControl(RichContent.ascx),该控件经由过程contentPath属性指定。别的,impressions属性设置为5。
<?xmlversion="1.0"encoding="utf-8"?>
<contents>
<content>
Thingsarejustaverage...neitherpositivenornegative...
</content>
<contentimpressions="3"keyword="positiveComments">
<b>Youwillsoonseeaworkplacepromotion.</b>
</content>
<contentkeyword="positiveComments">
<![CDATA[
Happinessis<i>justaroundthecorner!</i>
]]>
</content>
<contentcontentPath="~/RichContent.ascx"impressions="5"/>
</contents>
该内容文件必要保留在Web服务器的文件体系中。要显现特定文件的内容,只需将ContentRotator增加到ASP.NET页,并将它的ContentFile属性设置为内容文件的假造路径。
注要记着,XML是辨别巨细写的,因而XML元素的巨细写是主要的。假如您没有利用准确的巨细写(比方,利用而非),则不会从内容文件检索这些内容项,从而失掉一个不收回任何内容项的ContentRotator控件。
声明性地指定内容项
很多ASP.NETWeb内置控件同意其年夜多半属性用Web控件的声明性语法来指定。比方,您能够指定经由过程声明性语法创立DataGrid的特定DataGridColumn。ContentRotator供应相似的声明性语法来指定它的内容项。关于ContentRotator要随机显现的每一个项,请在标志中增加一个元素。每一个元素能够包括以上司性:
•Content
•Impressions
•Keyword
•ContentPath
这些属性分离映照到元素的文本部分,和XML内容文件架构的impressions、keyword和contentPath属性。(您能够选择将Content属性指定为该外部标志的文本内容,以下面的前两个实例所示。)上面显现用于ContentRotator的声明性语法,个中带有后面利用的四个内容项。
<skm:ContentRotatorid="ContentRotator1"runat="server">
<skm:ContentItem>Thingsarejustaverage...neitherpositivenor
negative...</skm:ContentItem>
<skm:ContentItemImpressions="3"Keyword="positiveComments"><b>Youwillsoonseeaworkplacepromotion
</b></skm:ContentItem>
<skm:ContentItemContent="Happinessis<i>justaroundthe
corner!</i>"Keyword="positiveComments"></skm:ContentItem>
<skm:ContentItemContentPath="~/RichContent.ascx"Impressions="5"></skm:ContentItem>
</skm:ContentRotator>
请注重,利用该声明性语法时,您无需利用Content属性来本义HTML字符。
以编程体例指定内容
为了帮忙内容和内容项的观点,ContentRotator包括两个类:
•ContentItem―笼统地暗示带有诸如Content、ContentPath、Keyword、Impressions等属性的内容项。
•ContentItemCollection―强范例化的ContentItem实例汇合。
ContentRotator控件包括范例ContentItemCollection的一个Items属性。您能够经由过程将ContentItem实例增加到ItemsItems属性,以编程体例指定,当随机选择项时ContentRotator应当思索的内容项。和其他ASP.NET服务器控件一样,增加到Items属性的内容存储在该控件的视图形态中,因而,您只需在第一次页会见时增加这些项,而不是在随后的回调中举行增加。上面的代码片断显现了怎样以编程体例增加后面两个示例中利用的内容项汇合:
privatevoidPage_Load(objectsender,System.EventArgse)
{
if(!Page.IsPostBack)
{
//onlyneedtoloadcontentitemsonfirstpagevisitC
theyarepersistedacross
//postbacksintheViewState...
ContentRotator1.Items.Add(newContentItem("Thingsarejust
average...neitherpositivenornegative..."));
ContentRotator1.Items.Add(newContentItem("Youwill
soonseeaworkplacepromotion",string.Empty,"positiveComments",3));
ContentItemthirdCI=newContentItem();
thirdCI.Content="Happinessisjustaroundthe
corner!";
thirdCI.Keyword="positiveComments";
ContentRotator1.Items.Add(thirdCI);
//Adddynamiccontent
ContentRotator1.Items.Add(newContentItem(string.Empty,
"~/RichContent1.ascx",string.Empty,5));
}
}
如您所见,ContentItem类有大批机关函数重载,它们能够将创立新ContentItem实例并设置其属性的代码减至一行。
假如您不想浏览代码具体信息,而间接入手下手在ASP.NET使用程序中利用ContentRotator,则您能够跳过下文并从本文顶部的链接下载控件。该下载包含ContentRotator控件(以C#编写)的完全源代码,和一个示例ASP.NETWeb使用程序(也以C#编写),该程序显现针对下面所会商用例的办理计划。别的,该下载还包含一个表面大度、经编译的匡助文件,用来匡助决意利用ContentRotator控件的页面开辟职员。
断定要显现的内容项
每次会见带有ContentRotator控件的页时,ContentRotator必需决意要随机显现甚么内容。每一个内容项有一个相干的impressions值,该值影响到该内容项相对其他内容项被选中的大概性。该impressions参数是一个正整数值,在不指定的情形下,默许值为1。别的,每一个内容项能够有一个可选的关头字参数。假如指定ContentRotator控件的KeywordFilter属性,则将用于显现的内容项汇合限定为那些具有婚配关头字值的内容项。
用于随机选择内容项的算法的事情体例为:将每一个可使用的内容项以端对端体例举行结构,从而构成一行。每一个内容项的长度是它的impressions值,这意味着该行的全体长度是可使用的内容项impressions的总和。接上去,选择一个小于总长度的随机数,而要显现的内容项是位于随机数地位的内容项。以图形体例阐释该算法。
.
为了使用此算法,ContentRotator控件起首必要检索要思索的内容项列表。想必您还记得,该列表大概作为XML文件驻留在磁盘上,它能够用ContentRotator的声明性语法指定,大概以编程体例供应。让我们看看怎样利用这三种手艺会见该内容项列表。
从内容文件读取内容数据
ContentRotator有一个ContentItemCollection范例的Items属性,它包括由ContentRotator控件思索的可使用内容项集。(信任您还记得,该可使用内容项集依附因而否设置了该控件的KeywordFilter属性,假如设置了该属性,还取决于内容项的关头字参数。)Items属性经由过程挪用GetFileData(virtualFilePath)办法,在Load事务中举行添补。该办法前往一个ContentItemCollection实例,它包括由virtualFilePath参数指定的内容文件中的一切内容项。
在每次会见页面时翻开、读取并剖析全部内容文件将是有效和不用要的,出格是在思索到该文件大概很少举行变动的情形下。要进步功能,必要利用一个文件依附项缓存该内容文件中的项。这意味着该内容文件中的项将驻留在用于进步功能的缓存中,可是当基本内容文件修正时,该缓存项将主动生效。以下GetFileData(filePath)办法的代码阐释该缓存举动:
//Seeiftheitemexistsinthecache
stringcacheKey=string.Concat("ContentRotateCacheKey:",
physicalFilePath);
ContentItemCollectioncachedContent=(ContentItemCollection)
HttpContext.Current.Cache;
if(cachedContent==null)
{
//its*not*inthecache,mustmanuallygetthefiledataandcacheit
cachedContent=LoadFile(physicalFilePath);
if(cachedContent==null)
returnnull;
else
//Addthecontenttothecache
HttpContext.Current.Cache.Insert(cacheKey,cachedContent,
newCacheDependency(physicalFilePath));
}
//returnthecachedcontent
returncachedContent;
变量physicalFilePath包括到该内容文件的物理路径,并用于构成缓存键。这确保了每一个分歧的内容文件都将有其本人的缓存项。接上去,会见Cache工具,从而检索名为cacheKey的缓存项的值。假如该项是null(因为该缓存中没有拔出此类项,大概缓存项已生效),则来自内容文件的内容和基于内容文件的缓存依附项一同加载并拔出到该缓存中。
LoadFile(physicalFilePath)办法利用XPathNodeIterator迭代经由过程内容文件,从而扫除多种属性和文本内容,并为该内容文件中的每项天生一个ContentItem实例。每一个ContentItem实例增加到ContentItemCollection,它在该办法的了局中前往。以下代码显现了迭代经由过程内容文件中每项的历程;fStream是该内容文件的一个翻开的文件流。
//UseanXPathNavigatortoiteratethroughtheXMLelementsintheContentFile
reader=newXmlTextReader(fStream);
XPathDocumentxpDoc=newXPathDocument(reader);
XPathNavigatorxpNav=xpDoc.CreateNavigator();
XPathNodeIteratorxmlItems=xpNav.Select("/contents/content");
XPathExpressioncontentExpr=xpNav.Compile("string(text())");
XPathExpressioncontentPathExpr=xpNav.Compile("string(@contentPath)");
XPathExpressionkeywordExpr=xpNav.Compile("string(@keyword)");
XPathExpressionimpressionsExpr=xpNav.Compile("string(@impressions)");
if(xmlItems==null)
thrownewFormatException("ContentFileininvalidformat.");
else
{
while(xmlItems.MoveNext())
{
stringcontent=(string)xmlItems.Current.Evaluate(contentExpr);
stringcontentPath=(string)xmlItems.Current.Evaluate(contentPathExpr);
stringkeyword=(string)xmlItems.Current.Evaluate(keywordExpr);
stringimpressionsStr=(string)xmlItems.Current.Evaluate(impressionsExpr);
intimpressions=1;//defaultimpressionsvalueis1
if(impressionsStr!=null&&impressionsStr.Length>0)
impressions=Convert.ToInt32(impressionsStr,
CultureInfo.InvariantCulture);
contentItems.Add(newContentItem(content.Trim(),
contentPath,keyword,impressions));
}
}
XPathNodeIterator逐行经由过程每一个元素,从而使用一个XPathExpression来选择每一个属性和文本内容。当迭代每一个项以后,创立ContentItem实例,并为它的属性分派来自XPathExpression的值。每一个ContentItem实例增加到ContentItemCollection实例,该实例稍后从LoadFile(physicalFilePath)办法前往。
以编程体例读取内容数据
为了以编程体例将项增加就任何范例的Web控件,您必要实行以下三个步骤:
1.创立一个暗示要增加项的类。
2.创立一个暗示项汇合的类。
3.为该Web控件增加一个属性,其范例为在步骤2中界说的类。该属性保存用于该控件的项集。
要实践检察这些步骤,请思索内置的ASP.NETDropDownListWeb控件,该控件包括构成DropDownList的可用选择的项汇合。每项都由ListItem类的实例暗示(步骤1)。ListItemCollection类供应强范例的ListItem实例汇合(步骤2),并且DropDownList类具有范例ListItemCollection的一个Items属性(步骤3)。使用ASP.NET页的源代码片断,DropDownList能够经由过程以下语法使ListItem实例以编程体例增加到个中:
DropDownList1.Items.Add(newListItem(text,value));
为了利用ContentRotator完成相似的功效,我创立了ContentItem类来暗示一个特定的内容项。如前所述,该类具有特定于内容项的属性,比方,Content和Impressions,等等。接上去,我创立了一个ContentItemCollection类,它供应ContentItem实例的强范例汇合。最初,我在ContentRotator类中创立了一个ContentitemCollection范例的Items属性。
当创立了这些类和属性以后,页面开辟职员可以以编程体例将内容增加到ContentRotator中,其语法与DropDownList的语法分歧:
ContentRotator1.Items.Add(newContentItem(content));
ContentRotator1.Items.Add(newContentItem(content,contentPath,
keyword,impressions));
...
从该控件的声明性语法读取内容
除可以以编程体例指定项以外,良多Web控件也能够使页面开辟职员可以经由过程该控件的声明性语法指定项集。比方,经由过程DropDownList,可以以声明体例申明ListItem,以下所示:
<asp:DropDownListrunat="server"...>
<asp:ListItemValue="value1">text1</asp:ListItem>
<asp:ListItemValue="value2"Text="text2"></asp:ListItem>
...
<asp:ListItemValue="valueN">textN</asp:ListItem>
</asp:DropDownList>
将该功效增加到ContentRotator十分复杂,这是由于我们已界说了ContentItem类,并且还具有效于ContentRotator控件的Items属性。我们只需利用两个属性,以便唆使用声明性语法指定的项映照到该ContentRotator的Items属性。
起首,在类级别增加ParseChildren()属性,从而唆使应当剖析该子标志,并且它映照到Items属性:
publicclassContentRotator:Control
{
...
}
最初,将PersistenceMode()属性增加到Items属性声明,从而唆使该Items属性将作为外部默许属性保存。
publicContentItemCollectionItems
{
get{...}
}
这就是一切的步骤。经由过程这两个属性,页面开辟职员可以用该控件的声明性语法指定内容项,以下所示:
<skm:ContentRotatorrunat="server"...>
<skm:ContentItemContent="content"ContentPath="contentPath"
Keyword="keyword"Impressions="impressions"></skm:ContentItem>
...
</skm:ContentRotator>
必要注重的是,关于我们以后的代码,ContentItem实例的一切属性必需作为元素的属性指定。幻想情形下,页面开辟职员将可以指定静态内容,办法是使用Content属性或和标志之间的文本内容。为此,我们必要将一小段代码增加到ContentItem类,从而唆使该类应当剖析外部文本内容。
出格是,ContentItem类必要完成IParserAccessor接口,该接口界说一个复杂的办法AddParsedSubObject(object)。AddParsedSubObject(object)办法以声明性语法传进元素的内容。假如外部内容是纯文本,则传进LiteralControl实例。在本例中,我们想将LiteralControl的Text属性分派给ContentItem实例的Content属性。这是经由过程以下代码完成的:
publicclassContentItem:IParserAccessor
{
...
publicvoidAddParsedSubObject(objectobj)
{
if(objisLiteralControl)
Content=((LiteralControl)obj).Text;
else
thrownewHttpException(...);
}
#endregion
}
选择一个随机内容项
当在Load事务中检索ContentRotator的Items属性以后,挪用SelectContentFromItems()办法。该办法前往从Items汇合随机选择的ContentItem实例。假如设置了ContentRotator的KeywordFilter属性,它将从汇合中移除不成用的项。然后,它为残剩的项断定impressions参数的总数,并在0和impressions总数减往1所得的数之间随机选择一个数。基于该随机数选择并前往得当的内容项。
以下代码显现怎样移除不成用项和怎样盘算impressions的总数(在设置了KeywordFilter属性的情形下)。接上去,选择一个随机impressions,并前往得当的ContentItem实例。
//DeterminethesumoftheImpressions
inttotalWeight=0,i=0;
stringcontrolsKeywordFilter=this.KeywordFilter;
ContentItemCollectionfilteredArray=newContentItemCollection();
for(i=0;i<Items.Count;i++)
//onlyaddthecontentitemtothelistoffilteredcontent
//itemsiftheKeywordFilterpropertyhasntbeensetor,
//ifithas,iftheKeywordFiltermatchesthecontentitems
//keywordattribute.
if(controlsKeywordFilter.Length==0||
CultureInfo.InvariantCulture.CompareInfo.Compare(Items.Keyword,controlsKeywordFilter,
CompareOptions.IgnoreCase)==0)
{
totalWeight+=Items.Impressions;//incrementthetotalWeight
filteredArray.Add(Items);
}
//Randomlychooseanumberbetween0andtotalWeight-1
intrandomWeight=random.Next(totalWeight);
totalWeight=0;
//NowgrabtheappropriateContentItembasedonrandomWeight
i=0;
while(i<filteredArray.Count&&(totalWeight+
filteredArray.Impressions)<=randomWeight)
totalWeight+=filteredArray.Impressions;
returnfilteredArray;
供应静态内容
断定了显现哪一个内容项就乐成了一半。我们也必要可以实践显现所选的内容项。这是在SelectContentFromItems()办法指定显现甚么内容项以后,在Load事务中完成的。假如该项包括静态内容(即,假如它没有设置它的ContentPath属性),则会创立一个新LiteralControl实例,并将它增加到ContentRotator的控件条理布局,将其Text属性设置为要显现的静态内容的值。
可是,假如要显现的内容是静态的(即,设置了它的ContentPath属性,从而指定将供应静态内容的UserControl),则挪用Page的LoadControl(path)办法加载特定UserControl的控件条理布局。该控件条理布局的根经由过程LoadControl()办法前往,并且该控件增加到ContentRotator的控件条理布局。以图形体例阐释该历程。
.
默许情形下,ContentRotator将随机选择要在每次会见页时显现的内容项,包含针对不异页的回调。假如您必要跨回调来显现不异的随机检索内容项,则只需复杂地将ContentRotator的NewContentOnPostbacks设置为false。假如您要利用必要回调的静态内容(比方,一个提醒用户举行某些输出,并使用回调显现关于该输出的具体信息用户控件),然后您必要将NewContentOnPostbacks设置为false。假如您使NewContentOnPostbacks保存其默许值true,则当该用户从随机选择的UserControl回调时,ContentRotator大概选择一个分歧的内容项,而如许会丧失回调数据。
实践上,不管加载的内容是静态的仍是静态的,假如NewContentOnPostbacks属性设置为true,ContentRotator的控件条理布局城市禁用它的视图形态。这是由于回调时,ContentRotator大概选择与前次会见页面时分歧的内容项。假如本例中ContentRotator不由用视图形态,则假如已随机选择了一个分歧的内容项,将在加载视图形态阶段激发一个非常。可是,假如NewContentOnPostbacks属性设置为false,则保持ContentRotator控件条理布局的视图形态。
注有关利用LoadControl()办法以编程体例加载用户控件的更多信息,请必定要浏览我之前撰写的文章AnExtensiveExaminationofUserControls。关于视图形态和相干成绩的信息位于UnderstandingASP.NETViewState。
自界说所选的内容项
ContentRotator的功效请求之一是,同意页面开辟职员在内容项中指定静态占位符。比方,页面开辟职员应当可以创立带有内容文本“Thecurrenttimeis[]”的内容项,并用以后体系工夫静态代替[]占位符。我得出两个办法来办理这个成绩:
1.供应一个预界说的占位符集,用于举行静态交换。
2.同意页面开辟职员决意利用甚么占位符和用甚么值交换它们。
第一个选项是这两其中较简单完成的一个:我能够在ContentRotator控件的Load事务中举行反省,该事务可使用响应的静态值体系地交换所选内容项中的一切预界说占位符。固然该办法易于完成,但我想它不会供应页面开辟职员所需的自界说级别。
因而,我将界说占位符并添补静态值的事情完整留给页面开辟职员。页面开辟职员能够制造他必要的任何占位符,从而在该内容文件中或经由过程声明性语法将它们增加到这些内容项的文本内容。我只需为页面开辟职员供应映照到所选内容项的机制。为此,我利用ContentRotator公然一个ContentCreated事务。每次会见页面时,只需选择要显现的内容项,就会引发该事务。
页面开辟职员能够创立一个用于该事务的事务处置程序。在该事务处置程序中,页面开辟职员将吸收所选的用于显现的ContentItem实例。此时,能够搜刮该内容项的文原本猎取要用其静态值交换的占位符。上面的示例分析这一举动。ContentRotator有三个经由过程声明性语法界说的内容项,个中两个带有静态占位符。
<skm:ContentRotatorid="ContentRotator1"runat="server">
<skm:ContentItemContent="Thecurrenttimeis
[]."></skm:ContentItem>
<skm:ContentItemContent="Hello,World!Nothingdynamic
here!"></skm:ContentItem>
<skm:ContentItemContent="Welcometopage
[]."></skm:ContentItem>
</skm:ContentRotator>
在ASP.NET页的代码埋没类中,创立事务处置程序并将其绑定到ContentRotator的ContentCreated事务。该事务处置程序的第二个参数是范例ContentCreatedEventArgs,该参数在其ContentItem属性中包括所选的ContentItem实例。如以下代码所示,该事务处置程序利用以后体系工夫交换[]的任何实例,并利用以后页的URL交换[]的任何实例。
privatevoidContentRotator1_ContentCreated(objectsender,
skmContentRotator.ContentCreatedEventArgse)
{
//Replace[]withDateTime.Now.TimeOfDay
e.ContentItem.Content=e.ContentItem.Content.Replace("[]",
DateTime.Now.TimeOfDay.ToString());
//Replace[]withRequest.RawUrl
e.ContentItem.Content=e.ContentItem.Content.Replace("[]",
Request.RawUrl);
}
注占位符(在本例中是[]和[])由页面开辟职员决意。即页面开辟职员可使用他选择作为占位符的任何称号和标志。比方,我们可使用*currentTime*(而不是[])作为占位符,从而将[]的一切实例交换为内容文件和事务处置程序中的*currentTime*。
小结
跟着.com泡沫的阑珊,诸如Microsoft的AdRotator一类的控件正渐渐过期。可是,AdRotator的观点是很好的,并且在良多计划中,一样平常内容转动控件证实是无价的。本文展现的ContentRotator控件应当合适这些情形中的年夜多半。ContentRotator供应的语义和语法与AdRotator控件的类似,包含用于内容项的一个impressions值,关头字选择,和一个同意页面开辟职员映照所选内容项的事务。别的,ContentRotator同意以声明体例指定它的内容项,并同意静态和静态内容。
祝人人编程兴奋!
什么叫数据库怎么样?什么意思?你想单学数据库。(其实变成是我问的) 比如封装性、继承性、多态性等等,这就解决了刚才谈到的ASP的那些弱点。封装性使得代码逻辑清晰,易于管理,并且应用到ASP.Net上就可以使业务逻辑和Html页面分离,这样无论页面原型如何改变。 由于CGI程序每响应一个客户就会打开一个新的进程,所以,当有多个用户同时进行CGI请求的时候,服务器就会打开多个进程,这样就加重了服务器的负担,使服务器的执行效率变得越来越低下。 可以看作是VC和Java的混合体吧,尽管MS自己讲C#内核中更多的象VC,但实际上我还是认为它和Java更象一些吧。首先它是面向对象的编程语言,而不是一种脚本,所以它具有面向对象编程语言的一切特性。 大哥拜托,Java在95年就出来了,微软垄断个妹啊,服务器市场微软完全是后后来者,当年都是Unix的市场,现在被WindowsServer和Linux抢下大片,包括数据库也一样。 如今主流的Web服务器软件主要由IIS或Apache组成。IIS支持ASP且只能运行在Windows平台下,Apache支持PHP,CGI,JSP且可运行于多种平台,虽然Apache是世界使用排名第一的Web服务器平台。 那么,ASP.Net有哪些改进呢? 但是目前在CGI中使用的最为广泛的是Perl语言。所以,狭义上所指的CGI程序一般都是指Perl程序,一般CGI程序的后缀都是.pl或者.cgi。
页:
[1]