zoukankan      html  css  js  c++  java
  • Asp.Net服务器控件编程学习记录:第一个Callback控件

    实现一个完整的Ajax功能,在代码方面,需要做如下四个方面的工作:

    1. 用于实现该功能的DOM“骨架”;
    2. 页面上发送Ajax请求的javascript代码;
    3. 服务器端处理该请求并返回处理结果的代码(可能为C#或VB书写);
    4. 页面上接收服务器处理结果并作出相应反应的javascript代码。

    下面从这四个方面来看第一个使用Callback实现Ajax功能的服务器控件,其功能很简单,就是实现无刷新验证输入内容是否为电子邮件格式。

    首先新建一个名为“mySolution”的解决方案,包含两个Project,类型分别为Web Site和ASP.NET Server Control,命名分别为"Web"和"DDRII"。其中Web引用DDRII,新建一页面名为AjaxTest.aspx;DDRII中新建一 ASP.NET Server Control类型的Item,命名为MyCallbackControl,继承WebControl和ICallbackEventHandler,主 要的代码编写工作都在这里面。

    接下来逐一实现上述4个工作。

    一、生成DOM骨架,代码如下

    代码
    1 protected override void RenderContents(HtmlTextWriter output)
    2 {
    3 output.AddAttribute(HtmlTextWriterAttribute.Id, "txtInput");
    4 output.AddAttribute(HtmlTextWriterAttribute.Type, "text");
    5 output.AddAttribute("onblur", "ExecuteCallback(this.value,null);");
    6 output.RenderBeginTag(HtmlTextWriterTag.Input);
    7 }

    所做的工作就是在控件呈现内容时画了一个输入框,令其id为"txtInput",失去焦点时执行ExecuteCallback方法。

    二、生成发送请求的javascript代码并放到页面上

    首先拼装js代码:

    代码
    1 StringBuilder strCallbackScript = new StringBuilder();
    2 strCallbackScript.Append("function ExecuteCallback(argument,context) {");
    3 strCallbackScript.Append(Page.ClientScript.GetCallbackEventReference(this,
    4 "argument", this.ClientCallbackFunction, "context"));
    5 strCallbackScript.Append(";}");

    发送Ajax请求的javascript主要是Page.ClientScript.GetCallbackEventReference方法生成 的,其第一个参数为相关的控件,第二个参数为向服务器传递的参数,第三个参数为客户端的回调方法名称,第四个参数为上下文。在外面包上一层作为新的方法 ExecuteCallback,减少需要理会的参数。

    ClientCallbackFunction为该控件的公共属性,使用者可在属性栏看到和设置它的内容:

    代码
    1 [Category("Appearance")]
    2  public string ClientCallbackFunction
    3 {
    4 get
    5 {
    6 String s = (String)ViewState["ClientCallbackFunction"];
    7 return ((s == null) ? String.Empty : s);
    8 }
    9 set
    10 {
    11 ViewState["ClientCallbackFunction"] = value;
    12 }
    13 }

    发送请求的代码被拼装好后,由Page.ClientScript.RegisterClientScriptBlock方法放到了页面上。在此之前进行了检验,确认是否此代码块已经被注册过了:

    1 if (!Page.ClientScript.IsClientScriptBlockRegistered("call"))
    2 {
    3 Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
    4 "call", strCallbackScript.ToString(), true);
    5 }

    以上代码均在控件的OnPreRender方法内,也就是要在呈现之前执行。

    三、服务器端的请求处理和结果返回

    控件只要继承并实现了ICallbackEventHandler接口,就具备了处理Callback方式请求的能力。

    代码
    1 #region ICallbackEventHandler Members
    2  public string GetCallbackResult()
    3 {
    4 return this.Result;
    5 }
    6  public void RaiseCallbackEvent(string eventArgument)
    7 {
    8 if (StringValidate.IsEmail(eventArgument.ToString()))
    9 {
    10 this.Result = "true";
    11 }
    12 else
    13 {
    14 this.Result = "false";
    15 }
    16 }
    17  #endregion

    RaiseCallbackEvent方法根据客户端传递的参数进行业务逻辑的处理,GetCallbackResult则将结果返回给客户端。

    四、页面上的内容

    页面上首先拖一个写的控件到上面:

    代码
    1 <body>
    2 <form id="formMain" runat="server">
    3 <div>
    4 <DDRII:MyCallbackControl ID="littleCallback" runat="server" ClientCallbackFunction="clientCallback" />
    5 </div>
    6 </form>
    7  </body>

    ClientCallbackFunction属性是可以在属性栏里设置的,这就是页面上的回调函数的名称。

    <script type="text/javascript">
    function clientCallback(text) {
    alert(text);
    }
    </script>

    在上述四个方面完成后,这就是一个完整可以运行的使用Callback方式实现Ajax功能的服务器控件了,当然,在此之前验证用的类是必须写好了的。

    代码
    1 using System.Text.RegularExpressions;
    2 namespace DDRII
    3 {
    4 class StringValidate
    5 {
    6 const string EmailValStr = @"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
    7
    8 public static bool IsEmail(string srcStr)
    9 {
    10 return IsValidate(EmailValStr, srcStr);
    11 }
    12
    13 private static bool IsValidate(string rule, string input)
    14 {
    15 Regex regex = new Regex(rule);
    16 return regex.IsMatch(input);
    17 }
    18 }
    19 }


    用html标签加jQuery实现同样功能的代码

    代码
    1 <head runat="server">
    2 <title></title>
    3 <script src="Scripts/jquery-1.4.2.min.js" type="text/javascript"></script>
    4 <script type="text/javascript">
    5 function s(txt) {
    6 alert(txt);
    7 }
    8 function e() {
    9 alert("Some Error occured!");
    10 }
    11 $(function () {
    12 $("#txtInput").blur(function () {
    13 $.ajax({
    14 url: "Sample.ashx",
    15 data: "content=" + escape($("#txtInput").val()),
    16 success: s,
    17 error: e
    18 });
    19 });
    20
    21 });
    22 </script>
    23 </head>
    24 <body>
    25 <form id="formMain" runat="server">
    26 <div>
    27 <input id="txtInput" type="text" />
    28 </div>
    29 </form>
    30 </body>
    31
    处理使用了Generic handler,也就是放在后缀名ashx的文件中的Sample类

    代码
    1 public class Sample : IHttpHandler
    2 {
    3 public void ProcessRequest(HttpContext context)
    4 {
    5 context.Response.ContentType = "text/plain";
    6 string content = context.Request.QueryString["content"];
    7 if (!StringValidate.IsEmail(content))
    8 {
    9 context.Response.Write("false");
    10 context.Response.End();
    11 }
    12 context.Response.Write("true");
    13 }
    14
    15 public bool IsReusable
    16 {
    17 get
    18 {
    19 return false;
    20 }
    21 }
    22 }
    可以使用自己定义的后缀名,比如“.ajax”,然后写个专门处理该后缀名的handler;接下来的事情在IIS7中很好办,在web.config中 注册一下就OK,但是IIS6比较恶心,不但要在web.config中写明是哪个handler处理这个后缀名的请求,还得在IIS6中配置,告诉 IIS6遇到后缀名“.ajax”的请求,就交给aspnet_isapi.dll去处理。

    客户端得到的html两相对比,服务器控件方式实现该功能增加了许多“额外”内容,再加上服务器控件有其自身的生命周期(Callback方式只运 行该周期中一部分)。这似乎就是很多人认为在大型Asp.NET网站上使用服务器控件会影响性能的地方,不过如果完全不使用服务器控件(包括自己写的和 VS的标准控件)的话,为什么不干脆用J2EE呢?我将继续学习服务器控件编程的内容,希望能在深入学习之后对这个问题能得出一个自己的观点。

  • 相关阅读:
    OpenGL 五
    OpenGL 四
    对UICollectionView的学习
    KVO的简单用法
    css在各浏览器中的兼容问题
    iOS学习笔记---网络请求
    UI学习笔记---第十六天XML JSON解析
    ui学习笔记---第十五天数据库
    UI学习笔记---第十四天数据持久化
    UI学习笔记---第十三天可视化设计 XIB, StoryBoard
  • 原文地址:https://www.cnblogs.com/luoyaoquan/p/2030439.html
Copyright © 2011-2022 走看看