再见西城 发表于 2015-1-16 22:50:54

ASP.NET编程:Hiding/Manipulating Databound Items(...

据说很厉害,甚至可以把C#也干掉^_^,不过也很复杂,本来C++已经够复杂的。有人甚至还提出把这个东东引进标准,我觉得基本上不可能的。ASP.NEToffersapowerfulwaytorenderinformationfromadatabaseorXMLfile:Databinding.However,sometimesyouneedtobeabletoperformthedatabindingforalmostalloftheitemsinthedatasource.Orperhapsyouhavesomespecialformattingorsecondarydatathatyouneedtousewitheachrowinthedatasource,sothatyouneedalittlefinercontroloverhowthedataisboundtothecontrol.Inthesecases,youwilltypicallyneedtohandletheonItemDataBoundevent,whichisfiredforeachitemasitisboundtoyourcontrol.ThisgivesyouaLOTofflexibility,butunfortunatelythecodeisalittlebithairy.Hopefully,havinganexamplewillhelp!Firstofall,letmeexplainthatthisexampleistakenfromaLIVEapplication:myRegularExpressionLibraryoveratmyASP.NETtrainingwebsite,ASPSmith.com.Youcanseeitinactionbyclickinghere.Youllseewhatitisdoinginamoment.

FormyRegularExpressionLibrary,IhadseveralthingsIneededtoadjustbeyondthedefaultdatabindingthatmyDataGridprovided"out-of-the-box".Firstly,Ihadauser_idfieldinmydatathatIwantedtoconverttoalinktoausersemail.Next,IwantedtolimithowmuchoftheDescriptionfieldwasdisplayedonthesearchresultspage,toavoidcausingthepagetogetexcessivelylong(sincetheDescriptionfieldisaTEXTfieldinmydatabase,andcouldthereforebemanymegabyteslong).Lastly,IhadanEditlinkthatallowedtheowneroftheregularexpressiontoeditit,butIdidntwantthattobevisibleexceptifthecurrentuserwastheowneroftheexpression.Letsseehowthiswasdone.First,letstakealookatmy(ratherlengthy)Datagriddeclaration.Theimportantpartislistedinred.

default.aspxexcerpt<asp:DataGridid="dgRegexp"runat="server"AutoGenerateColumns="False"BorderColor="Black"BorderWidth="1"Style="margin-left:20px;"PageSize="5"AllowPaging="True"AllowCustomPaging="True"OnPageIndexChanged="dgRegexp_PageIndexChanged"onItemDataBound="dgRegexp_ItemDataBound"GridLines="Horizontal"PagerStyle-Mode="NumericPages"PagerStyle-HorizontalAlign="Center"PagerStyle-Position="TopAndBottom"PagerStyle-Width="100%"HeaderStyle-BackColor="#CC0000"HeaderStyle-Font-Bold="True"HeaderStyle-Font-Name="Verdana"HeaderStyle-Font-Size="9pt"HeaderStyle-ForeColor="White"ItemStyle-Font-Name="Arial"ItemStyle-Font-Size="8pt"AlternatingItemStyle-BackColor="#DDDDDD">

Thisevent,onItemDataBound,issupportedbyanycontrolthatsupportsdatabinding.YoucanuseitwithDataGrids,DataLists,Repeaters,etc.Inthiscase,Ihavemappedminetothe"dgRegexp_ItemDataBound"eventhandler,whichwelltakealookatnow:

default.aspxexcerptprotectedvoiddgRegexp_ItemDataBound(ObjectSender,DataGridItemEventArgse)
{
//ForItemsandAlternatingItems,
//convertuseridtoemaillink
//truncatedescription
//hideeditlinkifnotowner
if(e.Item.ItemType==ListItemType.Item||e.Item.ItemType==ListItemType.AlternatingItem)
{
Trace.Write("ItemDataBound",e.Item.DataItem.GetType().ToString());

intuser_id=Int32.Parse(((System.Data.Common.DbDataRecord)e.Item.DataItem)["user_id"].ToString());
Trace.Write("ItemDataBound","user_id:"+user_id.ToString());

ASPAlliance.DAL.UserDetailsobjUser=ASPAlliance.DAL.User.getUserDetails(user_id);
((System.Web.UI.WebControls.HyperLink)e.Item.FindControl("myuser")).Text=
objUser.first_name+""+objUser.last_name+"("+objUser.email+")";
((System.Web.UI.WebControls.HyperLink)e.Item.FindControl("myuser")).NavigateUrl="mailto:"+objUser.email;
Trace.Write("ItemDataBound","myuser.Text:"+((System.Web.UI.WebControls.HyperLink)e.Item.FindControl("myuser")).Text);

Stringdesc=((System.Data.Common.DbDataRecord)e.Item.DataItem)["description"].ToString();
if(desc.Length>100)
{desc=desc.Substring(0,99);
desc+="...";
}
((System.Web.UI.WebControls.Label)e.Item.FindControl("description")).Text=desc;
ASPAlliance.DAL.Securitysec=newASPAlliance.DAL.Security(this.Request);
if((sec.user_id==0)||(sec.user_id!=user_id)||(!sec.isAuthenticated))
{
((System.Web.UI.HtmlControls.HtmlTableCell)e.Item.FindControl("editTD")).Visible=false;
}}}}


Ok,nowthatswhatIcallanexample!Noneofthatwussylittle"justfordemonstration"threelinesofcodestuffforus.No,weregoingtogoalloutandshowyousomethingbiganduglythatactuallysitsonaproductionsite.Butdontfear,itwillallbecleartoyouinamoment,ifitisntalready(evenifyouonlyknowVB).Letsbreakthisdown.

Thefirst6linesdeclareourmethodandthrowinsomecomments.AsIsaid,IbasicallyhavethreethingsIwanttodohere:

Convertuseridtoanemaillink
TruncatetheDescriptionfield
HidetheEditlinkifcurrentuserisnottheowner
Theonlythingyoureallyneedtowatchhereistomakesurethatyoursecondparameterstypeiscorrectforthecontrolyouareusing.Thisisprettyself-explanatory,butifyoucantfigureitout,youcanalwayslookatthedefinitionoftheparticularcontrolyouareusingintheClassBrowser.ForyouVB.NETusers,justconvert"//"toasinglequote,getridofthe{andswitchtheparameterstothetypeisfollowingthenameandhas"As"infrontofit.

Next,weneedtomakesureweredealingwiththecorrectitemtype.Sincethiseventisraisedforeveryitemintheboundcontrol,includingItems,AlternatingItems,Separators,Headers,Footers,etc.(completelist),weneedtospecifywhichkindsofitemsweareconcernedwith.Inthiscase,wejustwanttodealwiththemainsectionofthecontrol,sowechecktomakesuretheiteminquestioniseitheranItemoranAlternatingItem.Thisishandledbytheifstatement.Wegetthecurrentitemfromourinputparameter,e,andcompareittotheItemTypesweareconcernedwith.ForyouVBguys,||means"Or".

Note:IneglectedtousealternatingitemswhenIfirstwrotethisapplication,sotheusersemailwasdisplayedforeveryotheritem,buttheusersIDwasdisplayedfortheothers!

Ok,nowIvegotsomeTracinginplacetohelpmewithdebugging.ThisjustoutputsthetypeofthecurrentItem,andletsmeverifythatitisinfacteitheranItemoranAlternatingItem.Youcanleavethisoutofyourimplementation.

NextIgrabtheuser_id.Thisisoneuglypieceofcode.Letmerepeatithereandgothroughitpiecebypiece:
intuser_id=Int32.Parse(((System.Data.Common.DbDataRecord)e.Item.DataItem)["user_id"].ToString());Letsstartwiththeinnermostparentheses,inred.ThisisC#smethodofTypeCasting,andisnecessarytoconvertthecurrentDataItemtotheDbDataRecordtype.Theorangesetofparenthesescompletesthisoperation.Forallintentsandpurposes,thecontentsoftheorangeparenthesesareconsideredtobeaDbDataRecord.Movingontothegreen,thisallowsustothenreferencethe"user_id"elementofthisrecord,usingC#sarray/collectionsyntax(inVBthiswoulduse()insteadof[]),andconvertthecontentstoaString,becausethatiswhatInt32.Parseexpects.Finallymovingouttotheblack,Int32.ParseconvertsaStringintoanint.Theresultsofthisconversionarethenstoredinmyuser_idvariableoftypeint.OnthenextlineIhavesomemorediagnosticcodetooutputtheuser_idtotheTracelog.

Ok,sonowwehaveauser_id.ThenextchunkofcodeusessomecustomcontrolsthatIwrotetohandlemyUsers.ThecontrolismodelledaftertheonesfoundintheIBuySpyApplication.Inthiscase,IUserDetailsclassthatholdsmyusersnameandemailaddressbycallingthegetUserDetailsmethodofmyUserclass.Thenextlineisanotherhairyone,though:
((System.Web.UI.WebControls.HyperLink)e.Item.FindControl("myuser")).Text=objUser.first_name+""+objUser.last_name+"("+objUser.email+")";
Again,startingfromthemiddlemostparens,wehaveanothertypecastingoperationbeingdone.TheredcodeisusedtoconverttheorangecodeintoaHyperLink.TheorangecodeisusedtofindthecontrolwhoseIDis"myuser"withinthecurrentitem.Inmytemplateformycolumninmydatagrid,Ihavean<asp:HyperLinkid="myuser"/>tagthatthiscoderefersto.Therestofthisblockofcodesetsthetextofthishyperlinktotheusersnameandemailaddress.ThehyperlinktaglookslikethisinmyDataGrid:<asp:hyperlinkID="myuser"Runat="server"><%#DataBinder.Eval(Container.DataItem,"user_id")%></asp:hyperlink>


Bynowthistypecastingisgettingtobeoldhat.Thenextlineprettymuchdoesthesamestuffasthepreviousline,butinthiscaseweresettingtheNavigateUrlpropertyofourHyperLinkto"mailto:"andtheusersemailaddress.Onceagainthisisfollowedbysomemorediagnostictracing.
((System.Web.UI.WebControls.HyperLink)e.Item.FindControl("myuser")).NavigateUrl="mailto:"+objUser.email;

Thatsitfortheemail.Task1iscomplete.Nowwewanttotruncatethedescriptionifitistoolong.Wedothisusingsimilartechniques.First,wegrabthe"description"fromthecurrentDataItemafterconvertingittoaDbDataRecordtype.Thenweconvertittoastringandassignittoavariable,desc(allinoneline).Next,wechecktoseeifitslengthismorethan100,andifitis,weconvertittojusttheleft100characters(usingSubstring--inVBwewouldhaveusedLeft())andtackona"..."totheendtoshowtheusersthatthereismoretext.Finally,weusetheFindControlsyntaxoncemoretolocatethedescriptionLabelcontrolwithinourtemplate,andsetitsTextpropertytotheresult.

Thats2tasksdown.Onetogo.ThisisthemostcommonlyaskedforfeatureofDataGridsandDataLists:howtohideaparticularroworitemwithinadataboundlist.Inthiscase,IusemycustomSecuritycontroltodetermineiftheuseristheownerofthecurrentregularexpression.Iftheyarent,oriftheyarentloggedinandAuthenticated,thenIsetthetablecellholdingmyEdittagsVisiblepropertytofalse.Inordertodothis,IhadtomakemytablecellanHtmlControlbyaddingrunat="server"toitandgivingitanID.Inamedthetablecell"editTD",andIcanuseFindControltolocatethecellwithinmyItemandaccessitsproperties.Thecellitselfislistedhere:<tdalign="right"valign="top"id="editTD"runat="server">
[<ahref=Edit.aspx?regexp_id=<%#Server.UrlEncode(DataBinder.Eval(Container.DataItem,"regexp_id").ToString())%>
title="Clicktoedit.">Edit</a>]
</td>
Thatsallthereistooit.Formostpeople,theywanttoknowhowtohidesomethingifitsvalueisnull.JustdothesamethingImdoinghere,butreplacetheifstatementthatisreferringtosecuritywithonethatchecksthevalueofthevariable.Youwillprobablyneedtousethe(System.Data.Common.DbDataRecord)e.Item.DataItem)syntaxdescribedearliertoaccessyourdataandcheckitfornull,butthatsallthereistoit.

Summary
Manipulatingorhidingindividualelementsofadataboundlistorgridisnotverydifficultonceyouknowafewtricks.However,thecodeISprettydarnedugly.Thecodeonthispageworks,andthatisthebestthingthatcanbesaidofanyexample.YoucanseeitinactionatASPSmithRegularExpressionLibrary.Ifyouhavetroublegettingthistoworkwithyourown,Isuggestthatyoufirstcompareyoucodewithmine,andifthatdoesntyieldanyinsight,asktheASP.NETDataexpertsontheASPNGDataListserv.Besuretoincludeyourfailingcodeinyourques
http://www.ckuyun.com/

无论谁倒了对双方阵营的粉丝们也是有害无益。

山那边是海 发表于 2015-1-20 05:34:38

主流网站开发语言之JSP:JSP和Servlet要放在一起讲,是因为它们都是Sun公司的J2EE(Java2platformEnterpriseEdition)应用体系中的一部分。

爱飞 发表于 2015-1-28 18:54:22

众所周知,Windows以易用而出名,也因此占据不少的服务器市场。

谁可相欹 发表于 2015-2-5 18:02:58

主流网站开发语言之ASP:ASP是微软(Microsoft)所开发的一种后台脚本语言,它的语法和VisualBASIC类似,可以像SSI(ServerSideInclude)那样把后台脚本代码内嵌到HTML页面中。虽然ASP简单易用,但是它自身存在着许多缺陷,最重要的就是安全性问题。

仓酷云 发表于 2015-2-13 02:12:46

业务逻辑代码都不必做任何改动;继承性和多态性使得代码的可重用性大大提高,你可以通过继承已有的对象最大限度保护你以前的投资。并且C#和C++、Java一样提供了完善的调试/纠错体系。

冷月葬花魂 发表于 2015-3-3 12:22:53

但是目前在CGI中使用的最为广泛的是Perl语言。所以,狭义上所指的CGI程序一般都是指Perl程序,一般CGI程序的后缀都是.pl或者.cgi。

莫相离 发表于 2015-3-11 11:02:02

有一丝可惜的是,这个系列太强了,Java阵营的朋友根本就是哑口无言...争论之火瞬间被浇灭,这不是我想这么早就看到的,但是值了。

乐观 发表于 2015-3-18 07:12:22

现在的ASP.net分为两个版本:1.1和2.0Asp.net1.1用VS2003(visualstudio2003)编程。Asp.net2.0用VS2005(visualstudio2005)编程。现在一般开发用的是VS2003。

深爱那片海 发表于 2015-3-25 13:10:20

使用普通的文本编辑器编写,如记事本就可以完成。由脚本在服务器上而不是客户端运行,ASP所使用的脚本语言都在服务端上运行,用户端的浏览器不需要提供任何别的支持,这样大提高了用户与服务器之间的交互的速度。
页: [1]
查看完整版本: ASP.NET编程:Hiding/Manipulating Databound Items(...