使用 ASP.NET 2.0 回调创建投票系统






4.36/5 (20投票s)
2007年11月18日
4分钟阅读

110456

2820
一篇关于如何使用 ASP.NET 客户端回调创建支持 AJAX 的投票系统的文章。
引言
在您的网站上创建投票系统可以帮助您更深入地了解用户的兴趣。我最近在 KofeeKoder 中添加了一个每周投票系统。在本文中,我将解释如何使用 ASP.NET 客户端回调创建支持 AJAX 的投票系统。
数据库架构
数据库模式只包含两个表
PollQuestions
:此表包含投票的所有问题PollChoices
:此表包含投票问题选项
看看下面显示的模式

存储过程
CREATE PROCEDURE usp_GetLastestPoll
AS
DECLARE @pqID int
SELECT @pqID = MAX(PollQuestionID) FROM PollQuestions
PRINT @pqID
SELECT q.PollQuestionID,q.[Text] AS PollText,c.PollChoiceID,
c.[Text] ChoiceText,c.Total FROM PollQuestions q JOIN PollChoices c
ON q.PollQuestionID = c.PollQuestionID WHERE q.PollQuestionID = @pqID
GO
投票控件架构
我想创建投票用户控件,使其不依赖于页面。让我们来看看下面的类图

现在,我将详细解释每个类
IPoll<code>
:IPoll
是一个接口,所有投票类都将使用它WeeklyPoll
:这是负责创建每周投票的类。它实现了IPoll
接口PollQuestion
:这是一个实体类,映射到数据库中的PollQuestions
表PollChoice
:这是一个实体类,映射到数据库中的PollChoices
表PollTableHelper
:这是一个辅助类,用于生成动态 HTML 表ControlToHtmlConvertor
:此类包含将控件转换为纯 HTML 的辅助方法DataAccess
:此类充当DataAccess
类,用于从数据库INSERT
和SELECT
投票
实现
让我们深入探讨实现细节。本文将介绍几个重要的类。有关完整的实现,您可以使用本文顶部的代码。
IPollInterface
所有希望公开投票功能的类都实现了 IPollInterface
。
public interface IPoll
{
string Create();
string GetStats();
}
WeeklyPoll
WeeklyPoll
是实现 IPoll
接口的类之一。实现如下所示
public class WeeklyPoll : IPoll
{
public string Create()
{
PollQuestion poll = PollQuestion.GetPoll();
return PollTableHelper.GenerateTableForPoll(poll);
}
public string GetStats()
{
PollQuestion poll = PollQuestion.GetPoll();
return PollTableHelper.GetPollStats(poll);
}
}
我将不讨论 PollTableHelper
类,因为代码仅用于构建表。您可以下载本文顶部提供的完整源代码并查看实现。
PollControl.ascx
PollControl.ascx 是一个用户控件,用于向用户显示投票。让我们先看看 PollControl.ascx 控件的 HTML 代码。
是的,就是这样!
现在,让我们看看代码隐藏文件
protected void Page_Load(object sender, EventArgs e)
{
RegisterCallbacks();
}
private void RegisterCallbacks()
{
string sbReference = Page.ClientScript.GetCallbackEventReference
(this, "arg", "ReceiveServerData", "context");
string cbScript = String.Empty;
// check if the script is already registered or not
if (!Page.ClientScript.IsClientScriptBlockRegistered("CallServer"))
{
cbScript = @" function CallServer(arg,context)
{ " + sbReference + "} window.setTimeout(CallServer,100); ";
Page.ClientScript.RegisterClientScriptBlock
(this.GetType(), "CallServer", cbScript, true);
}
}
在上面的代码中,我只是注册了回调。如果您有兴趣了解更多关于如何注册页面/用户控件以使用回调,请查看 本文。
注册回调方法的所有内容都相同,除了调用 window.setTimeout
函数。我之所以进行此调用,是为了在将 CallServer
方法注册到页面后立即触发它。我知道您可能在想为什么不在回调注册过程结束时直接调用 CallServer('', '')。不幸的是,这种方法不起作用,因为
CallServer
需要来自页面的参数。
为了使回调正常工作,您必须实现 ICallbackEventHandler
接口,如下所示
public partial class PollControl :
System.Web.UI.UserControl, ICallbackEventHandler
ICallbackEventHandler
接口包含两个方法:GetCallbackResult
和 RaiseCallbackEvent
。让我们看看下面的实现
public void RaiseCallbackEvent(string eventArgument)
{
// update the polls
string[] selection = eventArgument.Split(':');
if (selection.Length > 1)
{
PollQuestion.Update(Int32.Parse(selection[0]),
Int32.Parse(selection[1]));
// create a cookie for the user
CreatePollCookie();
}
}
当用户单击“投票”按钮进行投票时,会触发 RaiseCallbackEvent
。我检查用户是否选择了某个选项,如果选择了,则在数据库中更新该选项。更新选项后,我还会创建一个 cookie,以便用户在一段时间内无法再次投票。
我还可以使用 IP 地址来跟踪哪个用户已投票,但使用 IP 地址存在一些缺点。如果一个人在防火墙后面的局域网中,那么他或她进行的投票将是整个局域网的投票,因为连接到局域网的计算机位于防火墙后面,它们具有相同的 IP 地址。
CreatePollCookie
用于创建 HttpCookie
private void CreatePollCookie()
{
HttpCookie pollCookie = new HttpCookie("PollCookie");
pollCookie.Value = "PollCookie";
pollCookie.Expires = DateTime.Now.AddDays(7);
Response.Cookies.Add(pollCookie);
}
在将内容发送到客户端之前,会触发 GetCallbackResult
方法。
public string GetCallbackResult()
{
string result = String.Empty;
IPoll poll = new WeeklyPoll();
if (DoesCookieExists())
{
result = poll.GetStats();
}
else
{
result = poll.Create();
}
return result;
}
DoesCookieExists
方法确保,如果客户端已经投票,则您需要向她或他显示投票统计信息,否则显示投票。这是通过检查 cookie 的存在来完成的。
private bool DoesCookieExists()
{
if (Request.Cookies["PollCookie"] != null) return true;
else return false;
}
JavaScript 代码
所有 JavaScript 代码都存储在 Site.js 文件中。网站的所有页面都必须引用 JS 文件才能使投票控件正常工作。
function vote()
{
var pollWidget = document.getElementById("divPoll");
var inputElements = pollWidget.getElementsByTagName("INPUT");
var userSelection;
for(i=0; i<inputElements.length;i++)
{
if(isRadioButton(inputElements[i]))
{
if(inputElements[i].checked)
{
userSelection = inputElements[i].id;
break;
}
}
}
// call the server method to note the changes
CallServer(userSelection,'');
}
function ReceiveServerData(rValue)
{
document.getElementById("divPoll").innerHTML = rValue;
}
function isRadioButton(target)
{
return target.type == 'radio';
}
您可以在屏幕右上角 实时查看 投票控件。嘿!当您在那里时,请务必投下您的一票!
希望您喜欢这篇文章,祝您编程愉快!