.NET中“顶一下”/“踩一下”单次操作的实现_ide


在各种门户网站中“顶一下”“踩一下”到处可见,无论是博文还是新闻娱乐资讯,众多网站都推出了“顶一下”“踩一下”的功能,以考证此帖的实用性,而且单个用户或单个IP只允许对某贴顶或踩一次。此文将探讨此功能的具体实现,以及网站中通用超链接及按钮css样式的美化。


开发工具:Microsoft Visual Studio 2008 + Microsoft Sql Server 2005

运行环境:Windows 7 + .Net Framework 3.5


一、 数据库设计

这里模拟一个简单的博客,简单地设计了两张表,一张为博文表,一张为“顶”或“踩”的记录表,还有两个存储过程,一个为当用户点击“顶一下”或“踩一下”按钮时执行的存储过程,一个为查询博文包含顶和踩次数的详细信息时的存储过程。


.NET中“顶一下”/“踩一下”单次操作的实现_css_02.NET中“顶一下”/“踩一下”单次操作的实现_sql_03代码 create database Blog

go


use Blog

go


--博文表

create table Blog

(

b_id int primary key identity(1001,1),--编号

b_title nvarchar(64) not null,--博文标题

b_contents ntext not null,--博文内容

b_createtime datetime default(getdate()),--博文创建时间

b_creater nvarchar(32)--博文创建者

)

go


--顶或踩记录表

create table DingRecord

(

d_id int primary key identity(1,1),--编号

b_id int references Blog(b_id) not null,--博文编号

d_operactor varchar(32) not null,--顶或踩的操作者,若登录用户则为登录名,匿名用户则为IP地址

d_isDing bit not null--是否为顶,1则为顶,0则为踩

)

go


--顶或踩的时执行的存储过程

create procedure sp_Ding

@b_id int, --博文id

@d_operactor varchar(32), --顶或踩的操作者

@d_isDing bit --是否为顶

as

--先判断此博文是否已经被顶过或踩过

if((select count(*) from DingRecord where b_id = @b_id and d_operactor = @d_operactor) >= 1)

begin

select '0'--返回0,表明已经被顶过或踩过

end

else

begin

insert into DingRecord values(@b_id,@d_operactor,@d_isDing)

select '1'--返回1,表明成功地执行了顶或踩操作

end

go


--查询包含有顶或踩记录数的博文的存储过程

create procedure sp_Blog

@b_id int

as

declare @dingCount int,@caiCount int

select @dingCount = count(*) from DingRecord where b_id = @b_id and d_isDing = 1

select @caiCount = count(*) from DingRecord where b_id = @b_id and d_isDing = 0

select *,@dingCount as dingCount,@caiCount as caiCount from Blog where b_id = @b_id

go







当执行以下查询

select * from blog

select * from dingrecord

exec sp_Blog 1001

得到结果如下:


.NET中“顶一下”/“踩一下”单次操作的实现_ide_04


二、 页面设计

在这里我们建两个页面

1)BlogList.aspx即为博文列表页,在博文列表页将传递博文的Id到博文详细页,其中博文列表页的代码如下



.NET中“顶一下”/“踩一下”单次操作的实现_css_02.NET中“顶一下”/“踩一下”单次操作的实现_sql_03代码 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="BlogList.aspx.cs" Inherits="BlogList" %>

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title>博文列表</title>

<style type="text/css">

body

{

font-size:12px;

}

a:link,a:visited

{

text-decoration:none;

color:#666666;

}

a:hover

{

text-decoration:underline;

color:#0066cc;

}

</style>

</head>

<body>

<form id="form1" runat="server">

<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">

<HeaderTemplate><ol></HeaderTemplate>

<ItemTemplate>

<li><a href='BlogDetails.aspx?blogid=<%# Eval("b_id") %>'><%# Eval("b_title") %></a></li>

</ItemTemplate>

<FooterTemplate></ol></FooterTemplate>

</asp:Repeater>

<asp:SqlDataSource ID="SqlDataSource1" runat="server"

ConnectionString="<%$ ConnectionStrings:connstr %>"

SelectCommand="SELECT [b_id], [b_title] FROM [Blog]"></asp:SqlDataSource>

</form>

</body>

</html>





2) BlogDetails.aspx即为博文详细页,博文详细页面中按钮的点击实现了AJAX技术以达到无刷新的效果,“顶一下”,“踩一下”按钮还通过JAVASCRIPT在其onmouseover和onmouseout事件中修改了其样式中的背景图片,图片如下:

.NET中“顶一下”/“踩一下”单次操作的实现_css_07.NET中“顶一下”/“踩一下”单次操作的实现_html_08

.NET中“顶一下”/“踩一下”单次操作的实现_ico_09.NET中“顶一下”/“踩一下”单次操作的实现_ico_10

博文详细页中的两按钮触发了FormView的ItemCommand事件,将两按钮安置在UpdatePanel中以达到无刷新效果,页面代码如下:


.NET中“顶一下”/“踩一下”单次操作的实现_css_02.NET中“顶一下”/“踩一下”单次操作的实现_sql_03代码 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="BlogDetails.aspx.cs" Inherits="BlogDetails" %>

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

<title>博文详细页</title>

<style type="text/css">

.btncss

{

width: 194px;

height: 50px;

border-width: 0px;

background-color: Transparent;

font-size: 14px;

font-weight: bold;

color: #666666;

background-repeat: no-repeat;

display: block;

cursor: hand;

}

</style>

</head>

<body>

<form id="form1" runat="server">

<asp:ScriptManager ID="ScriptManager1" runat="server">

</asp:ScriptManager>

<asp:FormView ID="FormView1" runat="server" DataKeyNames="b_id"

DataSourceID="SqlDataSource1" onitemcommand="FormView1_ItemCommand">

<ItemTemplate>

<table border="0" cellpadding="0" cellspacing="0" style="font-size: 12px; width: 600px;">

<tr>

<td colspan="4" style="text-align: center; height: 50px; font-weight: bold; font-size: 16px;

color: Red;">

<%# Eval("b_title") %>

</td>

</tr>

<tr>

<td style="width: 60px; height: 30px;">

作者:

</td>

<td style="width: 240px; color: Red;">

<%# Eval("b_creater") %>

</td>

<td style="width: 60px;">

发布时间:

</td>

<td style="width: 240px; color: Red;">

<%# Eval("b_createtime") %>

</td>

</tr>

<tr>

<td colspan="4" style="padding: 10px;">

<%# Eval("b_contents") %>

</td>

</tr>

<tr>

<td colspan="4">

<asp:UpdatePanel ID="UpdatePanel1" runat="server">

<ContentTemplate>

<table border="0" cellpadding="0" cellspacing="0" style="width: 600px; height: 50px;">

<tr>

<td style="width: 206px;">

<asp:Button ID="BtnDing" runat="server" CssClass="btncss" Text='<%# "顶一下(" + Eval("dingCount") + ")" %>'

Style="background-image: url(Img/ding.jpg);" onmouseover="this.style.backgroundImage='url(Img/dinghover.jpg)';"

onmouseout="this.style.backgroundImage='url(Img/ding.jpg)';" CommandName="Ding" />

</td>

<td style="width:194px;">

<asp:Button ID="BtnCai" runat="server" CssClass="btncss" Text='<%# "踩一下(" + Eval("caiCount") + ")" %>'

Style="background-image: url(Img/cai.jpg);" onmouseover="this.style.backgroundImage='url(Img/caihover.jpg)';"

onmouseout="this.style.backgroundImage='url(Img/cai.jpg)';" CommandName="Cai" />

</td>

<td style="width:200px; color:Blue; font-size:12px; padding-left:20px;">

<asp:Literal ID="ltInfo" runat="server"></asp:Literal>

</td>

</tr>

</table>

</ContentTemplate>

</asp:UpdatePanel>

</td>

</tr>

</table>

<br />

</ItemTemplate>

</asp:FormView>

<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:connstr %>"

SelectCommand="sp_Blog" SelectCommandType="StoredProcedure">

<SelectParameters>

<asp:QueryStringParameter DbType="Int32" QueryStringField="blogid" Name="b_id" />

</SelectParameters>

</asp:SqlDataSource>

</form>

</body>

</html>





博文详细页后台代码:


.NET中“顶一下”/“踩一下”单次操作的实现_css_02.NET中“顶一下”/“踩一下”单次操作的实现_sql_03代码 using System;

using System.Collections.Generic;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Configuration;

using System.Data;


public partial class BlogDetails : System.Web.UI.Page

{

protected void Page_Load(object sender, EventArgs e)

{

//如果QueryString中不存在blogid参数或为空,则跳转到博文列表页面

if (!IsPostBack && (Request.QueryString["blogid"] == null || Request.QueryString["blogid"].ToString() == ""))

{

Response.Redirect("~/BlogList.aspx");

}

(FormView1.FindControl("ltInfo") as Literal).Text = "";

}


protected void FormView1_ItemCommand(object sender, FormViewCommandEventArgs e)

{

switch (e.CommandName.ToUpper())

{

case "DING":

Ding(true);

break;

case "CAI":

Ding(false);

break;

}

}


private void Ding(bool isDing)

{

string user;

//如果是已登录用户,则取其登录名

if (User.Identity.AuthenticationType == "Forms" && User.Identity.IsAuthenticated)

{

user = User.Identity.Name;

}

//若为匿名用户,则取其IP地址

else

{

user = Request.UserHostAddress;

}

SqlDataSource sqlds = new SqlDataSource();

sqlds.ConnectionString = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;

sqlds.SelectCommand = string.Format("exec sp_Ding {0},'{1}',{2}",Request.QueryString["blogid"].ToString(),user,isDing ? "1" : "0");

DataView dv = sqlds.Select(DataSourceSelectArguments.Empty) as DataView;

if (dv[0][0].ToString() == "1")

{

(FormView1.FindControl("ltInfo") as Literal).Text = "谢谢支持";


Button btn = FormView1.FindControl(isDing ? "BtnDing" : "BtnCai") as Button;

//截取原来的顶或踩的次数,然后加1

int newDingCount = int.Parse(btn.Text.Substring(btn.Text.IndexOf("(")+1, btn.Text.IndexOf(")") - btn.Text.IndexOf("(") -1)) + 1;

//给按钮重新赋值

btn.Text = (isDing ? "顶一下(" : "踩一下(") + newDingCount + ")";


}

else if(dv[0][0].ToString() == "0")

{

(FormView1.FindControl("ltInfo") as Literal).Text = "你已进行过此操作";

}

}

}





三、 运行效果

博文列表页效果:

鼠标移上去时,超链接变色并加下划线

.NET中“顶一下”/“踩一下”单次操作的实现_html_15

博文详细页效果:

鼠标未移过时:

.NET中“顶一下”/“踩一下”单次操作的实现_ico_16

鼠标移过时:

.NET中“顶一下”/“踩一下”单次操作的实现_ico_17

未点击按钮时:

.NET中“顶一下”/“踩一下”单次操作的实现_ide_18

点击“顶一下”按钮:

.NET中“顶一下”/“踩一下”单次操作的实现_sql_19

再次点击“顶一下”或“踩一下”按钮:

.NET中“顶一下”/“踩一下”单次操作的实现_css_20

整个过程不刷新网页