知识点:简单的邮件发送找回密码,缓存帮助类,商品列表展示以及分页展示,URL重写,Seo优化
图书商城项目-三
知识点:简单的邮件发送找回密码,缓存帮助类,商品列表展示以及分页展示,URL重写,Seo优化
邮件找回密码
构建的内容中我们应该带一个具有验证码一样功能的参数来做到防止用户的骚操作
一般的邮件发送
1 2 3 4 5 6 7 8 MailMessage mail = new MailMessage(); mail.From = new MailAddress("694176993@qq.com" ,"测试" ); mail.To.Add(new MailAddress("694176993@qq.com" )); mail.Subject = "代码发送邮件测试" ; mail.Body = "dotnet发送邮件测试" ; SmtpClient client = new SmtpClient("smtp.qq.com" ); client.Credentials = new NetworkCredential("694176993" ,"Chendi735~!~" ); client.Send(mail);
缓存的使用 我们可以构建一个简单的缓存帮助类,用于增删查改,
(正如之前所提的,缓存可以在如下地方用到:不需要实时更新但是又极其消耗数据库的数据,需要实时更新,但是更新频率不高的数据,在某个时刻访问量极大而且更新也很频繁的数据但是这个另当别论,要是没有设置过期时间那么缓存将一直存在? )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 using System;using System.Web;using System.Web.Caching;namespace Common { public class CacheHelper { public static object Get (string key ) { Cache cache = HttpRuntime.Cache; return cache[key]; } public static void Set (string key,Object obj ) { Cache cache = HttpRuntime.Cache; cache[key]=obj; } public static void Set (string key,Object obj, DateTime time ) { Cache cache = HttpRuntime.Cache; cache.Insert(key,obj,null ,time,TimeSpan.Zero); } public static void Delete (string key ) { Cache cache = HttpRuntime.Cache; cache.Remove(key); } } }
这样一来我们在没有缓存的时候调用数据库查询,但是以后我们就调用业务层来从缓存里面取我们所需要的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public string GetValue (string key ) { if (Common.CacheHelper.Get("Setting_" +key)==null ) { string value = dal.GetModel(key).Value; CacheHelper.Set("Setting_" + key,value ); return value ; } else { return Common.CacheHelper.Get("Setting_" + key).ToString(); } }
商品列表展示 通常而言的物品展示,都是循环某段模板,然后做好分页,那么最简单的我们就可以用到之前的reaper控件
前端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <asp:Repeater ID ="Repeater1" runat ="server" > <ItemTemplate > //循环内容 <table > <tbody > <tr > <td rowspan ="2" > <a href ="<%#Eval(" Id ","/BookDetail_ {0 }.aspx ") %> "> <img id="ctl00_cphContent_dl_Books_ctl01_imgBook" style="cursor: hand" height="121" alt="<%#Eval("Title") %>" hspace="4" src="<%#Eval("ISBN","/Images/BookCovers/{0}.jpg") %>" width="95"></a > </td > <td style ="font-size: small; color: red" width ="650" > <a class="booktitle" id="link_prd_name" href="<%#Eval("Id","/BookDetail_{0}.aspx") %>" target="_blank" name="link_prd_name"><%#Eval("Title") %></a > </td > </tr > <tr > <td align ="left" > <span style="font-size: 12px; line-height: 20px"><%#Eval("Author") %></span > <br > <br > <span style="font-size: 12px; line-height: 20px"><%# this.CurringStr(Eval("ContentDescription").ToString(),150)%></span > </td > </tr > <tr > <td align ="right" colspan ="2" > <span style="font-weight: bold; font-size: 13px; line-height: 20px">¥ <%#Eval("UnitPrice","{0:0.00}") %></span > </td > </tr > </tbody > </table > </ItemTemplate > <SeparatorTemplate > <hr /> </SeparatorTemplate > </asp:Repeater >
后端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public partial class BookList : System.Web.UI.Page { protected void Page_Load (object sender, EventArgs e ) { if (!IsPostBack) { BindBookList(); } } private void BindBookList ( ) { BLL.BookManager bookManager = new BookManager(); this .Repeater1.DataSource = bookManager.GetModelList("" ); Repeater1.DataBind(); } public string CurringStr (string str,int length ) { return str.Length>length?str.Substring(0 ,length)+"..." :str; } }
有两个需要注意的地方,因为用到了空间所以会产生一坨的viewstate,需要在webform的开头第一个标签后面加上 EnableEventValidation=”false” ,另外就是 SeparatorTemplate 这个是reaper的分割标签 ,注意别写在table里面
实现分页(每页划分10商品) 数据层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public int GetRecordCount ( ) { string sql = "select count(*) from Books" ; return Convert.ToInt32(DbHelperSQL.GetSingle(sql)); } public DataSet GetPageList (int start,int end ) { string sql = "select * from(select *,row_number()over(order by id) as num from Books) as t where t.num>=@start and t.num<=@end" ; SqlParameter[] parameters = new SqlParameter[] { new SqlParameter("@start" ,start), new SqlParameter("@end" ,end), }; return DbHelperSQL.Query(sql,parameters); }
逻辑层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public int GetPageCount (int pagesize ) { int recordCount = dal.GetRecordCount(); return Convert.ToInt32(Math.Ceiling((double ) recordCount / pagesize)); } public List<Book> GetPageList (int pageIndex,int pagesize ) { int start = (pageIndex - 1 ) * pagesize + 1 ; int end = pageIndex * pagesize; DataSet ds = dal.GetPageList(start, end); return DataTableToList(ds.Tables[0 ]); }
web调用,就改写上面的商品展示列,采用分页的办法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public int pageindex; public int pageSize = 10 ; protected void Page_Load (object sender, EventArgs e ) { if (!IsPostBack) { BindBookList(); } } private void BindBookList ( ) { BLL.BookManager bookManager = new BookManager(); if (!int .TryParse(Request["pageIndex" ], out pageindex)) { pageindex = 1 ; } pageindex = pageindex < 1 ? 1 : pageindex; pageindex = pageindex > bookManager.GetPageCount(pageSize) ? bookManager.GetPageCount(pageSize) : pageindex; Repeater1.DataSource = bookManager.GetPageList(pageindex,pageSize); Repeater1.DataBind(); }
在可以需要一个简单的分页helper类(每页10个数据)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public static string GetPagaBar (int pageIndex, int pageCount ) { if (pageCount == 1 ) { return string .Empty; } int start = pageIndex - 5 ; if (start < 1 ) { start = 1 ; } int end = start + 9 ; if (end > pageCount) { end = pageCount; start = end - 9 < 1 ? 1 : end - 9 ; } StringBuilder sb = new StringBuilder(); if (pageIndex > 1 ) { sb.AppendFormat("<a href='?pageIndex={0}' class='myPageBar'>上一页</a>" , pageIndex - 1 ); } for (int i = start; i <= end; i++) { if (i == pageIndex) { sb.Append(i); } else { sb.AppendFormat("<a href='?pageIndex={0}' class='myPageBar'>{0}</a>" ,i); } } if (pageIndex < pageCount) { sb.AppendFormat("<a href='?pageIndex={0}' class='myPageBar'>下一页</a>" , pageIndex + 1 ); } return sb.ToString(); }
前端调用,在Repeater控件后面调用
1 2 3 <div class ="page_nav" > <%= Common.PageBarHelper.GetPagaBar(this.pageindex, this.pageSize)%>//记得别漏了=</div >
URL重写 为什么要进行重写,这是为了seo优化,比如说蜘蛛爬虫他不会趴带参数的地址,因此我们的URL必能参数,由于请求管道中的第八个事件就进行生成请求的对象,那么只能在请求管道的第八个事件前进行改写,最简单的就是建立一个全局应用类(Gobal.asax),里面有请求管道的第一个事件。也可以像之前那样自己定义一个类来实现相关接口然后改写
1 2 3 4 5 6 7 8 9 10 protected void Application_BeginRequest (object sender, EventArgs e ) { string str = Request.AppRelativeCurrentExecutionFilePath; Match match=Regex.Match(str, @"~/BookDetail_(\d+).aspx" ); if (match.Success) { Context.RewritePath("BookDetail.aspx?id=" +match.Groups[1 ].Value); } }
所以注意一点seo不会执行js,所以用a标签直接请求地址就好