使用 HTTP 模块在运行时创建服务器控件






4.88/5 (12投票s)
这是一个演示如何使用 HTTP 模块创建动态服务器控件的示例

引言
在本文中,我想分享一个我刚刚使用 HTTP 模块制作的非常简单的应用程序。
这一切都是关于使用 HTTP 模块生成动态 ASP.NET 服务器控件。我只是想玩弄一下这些东西,因此想出了这样一个应用程序,并考虑与他人分享。所以,关于我的应用程序没有什么好描述的。它是一个简单的表单,包含两个文本框控件,分别名为“姓名”和“年龄”,以及一个包含一个按钮的国家下拉列表。
目的是在运行时创建控件,填充列表控件,执行一些客户端验证,并在页面验证后访问控件值。
背景
在 ASP.NET 中运行时创建控件非常酷,并且有很多方法可以轻松完成。网上有很多很棒的文章。但我想要用一种不同的方式来做,所以我想,为什么不尝试使用 HTTP 模块呢!毕竟,让我们尝尝它的味道。
不过,在本文中,我不会深入探讨 HTTP 处理程序的细节,因为有很多优秀的文章可供参考,您可以从中获得很好的学习概览。我想在简短的介绍后,更专注于我制作的主题。
HTTP 模块简介
ASP.NET 在管道中处理每个请求。HTTPModule
和 HTTPHandler
是此管道的两个处理点。每次发出请求时,该请求都会经过多个 HTTP 模块,最后分配给一个 HTTP 处理程序,该处理程序决定系统将如何根据请求进行行为/响应。请求处理程序处理完请求后,响应会再次通过 HTTP 模块返回到应用程序。因此,HTTP 模块在处理程序执行之前和之后都会执行,并提供一种与请求交互的方法。有关更多信息,请参阅以下链接
必备组件
- .NET 3.0 框架
创建自定义 HTTP 模块
创建 HTTP 模块就像创建一个普通的 .NET 类一样简单,不同之处在于该类必须实现System.Web
命名空间中的IHttpModule
接口。该接口有两个方法,如下所示:
void Init(HttpApplication);
void Dispose();
步骤 1:创建一个新的 ASP.NET 网站,并选择 C# 作为语言。
步骤 2:右键单击项目,然后从“添加新项”对话框中选择一个类。
步骤 3:确保创建的类继承了IHttpModule
接口并实现了上面列出的方法。
注册 HTTP 模块
完成上述步骤后,我们需要在web.config文件中注册自定义处理程序。因此,打开web.config文件并搜索httpmodules
部分。接下来使用以下语法:
<httpmodules /><add name="[ModuleName]" type="[Assembly]" /></httpmodules />
HTTP 模块的动态控件生成和访问
在此应用程序中,我创建了两个名为“姓名”和“年龄”的文本框以及一个国家下拉列表。有一个提交按钮,其功能是仅对Age
字段执行客户端验证,如果年龄大于 50 且页面有效,它将访问这些值。
步骤 1:DynamicControls.cs 类继承自System.Web.UI.Page
、IHttpModule
,并实现了前面介绍的IHttpModule
的方法。
步骤 2:在Init
方法中,我调用了HttpApplication
类的PreRequestHandlerExecute
事件。
//Implementation of init method
public new void Init(HttpApplication context)
{
context.PreRequestHandlerExecute +=
new EventHandler(context_PreRequestHandlerExecute);
}
同一事件的处理程序负责检查页面是否有效,如果有效,则在Init()
方法中创建控件,并在Load()
事件中填充国家下拉列表。
//PreRequestHandlerExecute called
//Purpose: If a valid page is found, then call the various events of the page
// for performing the operations
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
//Gets the current http context
System.Web.HttpContext _httpContext = System.Web.HttpContext.Current;
if (_httpContext != null)
{
_page = _httpContext.Handler as System.Web.UI.Page;
//Valid page found
if (_page != null)
{
//Create controls
_page.Init += new EventHandler(_page_Init);
//Fill list controls(e.g. dropdowns)
_page.Load += new EventHandler(_page_Load);
}
else
{
return;
}
}
else
{
return;
}
}
步骤 3:ControlCreation.cs 类主要负责创建动态控件。为了正确放置,控件被放置在一个表中。
//Function : CreateControls
//Purpose: To create the controls
public void CreateControls(System.Web.UI.Page _pg)
{
//Building the controls
BuildGrid(_table, _lblName, _lblAge,
_lblCountry, _txtAge, _txtName, _rdBLstSex, _ddCountryList, _btnSubmit);
_pg.Form.Controls.Add(_table);
}
步骤 4:ControlCreation.cs 类主要负责创建动态控件。为了正确放置,控件被放置在一个表中。
//Function : CreateControls
//Purpose: To create the controls
public void CreateControls(System.Web.UI.Page _pg)
{
//Building the controls
BuildGrid(_table, _lblName, _lblAge, _lblCountry,
_txtAge, _txtName, _rdBLstSex, _ddCountryList, _btnSubmit);
_pg.Form.Controls.Add(_table);
}
步骤 5:FillCountry.cs 类负责填充国家下拉列表。
//Function Name:PopulateCountry
//Purpose: Fill country dropdown
public void PopulateCountry(System.Web.UI.Page _pg)
{
DataTable _dtCountry = GetCountryList();
DropDownList _ddlCountryList =
_pg.FindControl("ddlCountryList") as DropDownList;
_ddlCountryList.AutoPostBack = true;
if (_dtCountry != null)
{
if (_dtCountry.Rows.Count > 0)
{
AddBlankRow(ref _dtCountry, 0);
Populate(_dtCountry, _ddlCountryList);
}
}
}
步骤 6:年龄文本框只允许输入数字。JavaScript 函数AllowNumeric()
写在Validation.js文件中。此外,用户不能输入超过 50 岁的年龄,这是从提交按钮调用的。
private void ButtonAttributes(out Button _btnSubmit)
{
_btnSubmit = new Button();
_btnSubmit.ID = "btnSubmit";
_btnSubmit.Text = "Submit";
_btnSubmit.Style.Add("background", "#ffeec6");
_btnSubmit.Attributes.Add("onmouseover", "this.style.background='orange'");
_btnSubmit.Attributes.Add("onmouseout", "this.style.background='#ffeec6'");
_btnSubmit.Attributes.Add("onClick", "return CheckAge('txtAge');");
//If a valid page is found then access the data
_btnSubmit.Click += new EventHandler(_btnSubmit_Click);
}
步骤 7:为了在页面验证后访问数据,会触发提交按钮的点击事件。
private string AccessControlValues(string _value)
{
if (_page.FindControl("txtName") != null)
{
TextBox _txtName = (TextBox)_page.FindControl("txtName");
_value = _txtName.Text;
}
if (_page.FindControl("txtAge") != null)
{
TextBox _txtAge = (TextBox)_page.FindControl("txtAge");
_value = _txtAge.Text;
}
if (_page.FindControl("ddlCountryList") != null)
{
DropDownList _ddlCountryList =
(DropDownList)_page.FindControl("ddlCountryList");
_value = _ddlCountryList.SelectedItem.Text;
}
return _value;
}
注册 Httpmodule
执行方法如前所述。不过,我已将此示例应用程序的配置部分粘贴在此处。
<httpModules> < add name="DynamicControls" type="DynamicControls"></httpModules>
HTTP 模块的优点
HTTP 模块对于 ASP.NET 开发人员来说是一个便捷的工具。这里列出了一些优点:
- 与只能在全局或站点级别添加的 ISAPI 过滤器不同,HTTP 模块可以在站点、文件夹或文件级别添加。
- 可以在应用程序中跨多个实例重复使用。
结论
这只是一个展示 HTTP 模块可完成的小任务的示例,主要面向初学者。它只是大海中的一滴水。HTTP 模块的真正实力是巨大的,例如:
- 自定义缓存和会话处理机制
- HTTP 到 HTTPS 的转换,反之亦然
- 用户身份验证等
历史
- 2009年4月5日:首次发布