明天的明天 永远的永远 未知的一切 我与你一起承担 ??

是非成败转头空 青山依旧在 几度夕阳红 。。。
  博客园  :: 首页  :: 管理

玩玩AJAX之使用ashx文件响应来自JQuery的JSON请求.

Posted on 2009-05-09 15:42  且行且思  阅读(4135)  评论(1编辑  收藏  举报

ashx文件是.net 2.0新加的文件类型(其实在.net 1.0下已经可用,但是没有公开提供).

ashx文件和aspx文件有什么不同? 我们先新建一个ashx文件看看:

 


<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;

public class Handler : IHttpHandler {

public void ProcessRequest (HttpContext context) {
context.Response.ContentType
= "text/plain";
context.Response.Write(
"Hello World");
}

public bool IsReusable {
get {
return false;
}
}

}

 

看,比aspx简洁多了吧.只有一个文件,没有后台cs文件(基于代码安全考虑,后边我们会自己添加这个文件).ashx对比aspx文件,就好像少了cs文件.其实这就是ashx和aspx不同的地方,因为aspx要将前后台显示和处理逻辑分开,所以就弄成了两个文件,其实,在最终编译的时候,aspx和cs还是会编译到同一个类中去.这中间就要设计html的一些逻辑处理.而ashx不同,它只是简单的对web http请求的直接返回你想要返回的结果.比aspx少处理了html的过程.理论上,比aspx要快.

看看.net config文件中对两个文件类型请求的配置吧

 

config设置
<add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" />
<add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True" />

 

可以看到两个文件处理的类不一样(ashx处理的类叫SimpleHandleFactory,既然叫Simple,应该处理过程也比较Simple.响应速度也应该快点吧:)

只要具体继承了IHttpHandler如何处理的问题,我这里找到一篇早期的,介绍.net 2.0编译模型的问题.比较深奥,要慢慢鼓捣一下:

点击下载文章

鼓捣完了你就大概明白了ashx不过.net里面自定义好的一个请求格式,ashx文件类的文件的处理过程要比aspx要简单得多.

不说这些东西了.说会怎么利用ashx文件来实现我们的AJAX请求吧(其实实现和JQuery和JSON关系不大)

看看JS代码:

 


function getSecondaryContent(menuId){
$.getJSON(
"Article/FreshNews.ashx", function(data) {
var txt = "<ul class=\"news\">";
$.each(data,
function(i,n){
if(n.Url == "#")
txt
+= "<li><a href=\"#\" onclick=\"articleTitle_onclick('"+ n.ArticleId +"')\">"+ n.Title +"</a></li>";
else
txt
+= "<li><a href=\""+ n.Url +"\" target=\"_blank\">"+ n.Title +"</a></li>";
});
txt
+= "</ul>";
$(
"#"+menuId).after(txt);
});
}

 

和用其他文件没有差别吧?天下乌鸦一般黑!(汗~~~忽然冒出这个比喻.自己都觉得汗-_-||)

ashx文件如下:

 


<%@ WebHandler Language="C#" Class="FreshNews" %>

 

怎么样?是不是发觉少了点东西?和新建的文件不同了吧?呵呵,其实是我们将上边这句话以外的所有代码都放到App_Code里面了.

 

APP_Code
using System;
using System.Web;

public class FreshNews : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//context.Response.ContentType = "text/plain";
context.Response.ContentType = "application/json";
context.Response.Charset
= "utf-8";
string txt = "[{\"Title\":\"学习使用AJAX技术\",\"Url\":\"#\",\"ArticleId\":\"Art1234\"},{\"Title\":\"使用JQuery构建网站\",\"Url\":\"#\",\"ArticleId\":\"Art1235\"},{\"Title\":\"使用JSON文件传输数据\",\"Url\":\"#\",\"ArticleId\":\"Art1236\"}]";
context.Response.Write(txt);
}

public bool IsReusable
{
get
{
return false;
}
}

}

 

为什么要这样?因为MS说系统发布的时候ashx和asmx类型文件都是"生成程序集。原始文件保留在原位置,作为完成请求的占位符。",为了发布后不让人随便看到我们的代码,我们只有把代码移到App_Code里面了.不过,.net的反编译比什么都容易-_-|| 聊胜于无,心理安慰吧!

还有一个小插曲:因为我在web.config里面的设置是:

 

webconfig
<globalization fileEncoding="utf-8" requestEncoding="utf-8" responseEncoding="utf-8" responseHeaderEncoding="utf-8" />

 

就是因为JSON文件只支持Unicode编码,所以我就一狠心将所有编码都改成utf-8,想着这样做就一定没有错了.谁知道,js接收的数据中文死活是乱码,无论我怎么设置ContentType都是一样,差点没有把我气疯.

后来千辛万苦才想起好像这些编码和当前区域设置有关,续步尝试之下,发现只有将fileEncoding设置为"gb2312"才算正确获取到数据:

 


<globalization fileEncoding="gb2312" requestEncoding="utf-8" responseEncoding="utf-8" responseHeaderEncoding="utf-8" />

 

胡言乱语了这么久,都不知道自己要说什么了-_-|| 还是洗洗睡了.

 

忘了顺便说一句:在ashx文件用使用Session必须实现 IRequiresSessionState 接口.

 

 

参见:

 

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;

using System.Data;
using System.Configuration;

using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using _211;

using System.Web.SessionState;
public class Handler : IHttpHandler, IRequiresSessionState
{

    
string action = string.Empty;
    
string id = string.Empty;
    
string page = string.Empty;
    
string pagehtml = string.Empty;
    
string linkhtml = string.Empty;
    
int Pages = 5;

    
string commentparentid = string.Empty;
    
string commentuser = string.Empty;
    
string commenttext = string.Empty;
    
string commentvalidate = string.Empty;
  
    
public void ProcessRequest(HttpContext context) 
    {
        context.Response.ContentType 
= "text/plain";
        
//context.Response.Write("Hello World");

       
        action 
= context.Request.Params["action"];
        id 
= context.Request.Params["id"];
        page 
= context.Request.Params["page"];

        commentparentid 
= context.Request.Params["commentparentid"];
        commentuser 
= context.Request.Params["commentuser"];
        commenttext 
= context.Request.Params["commenttext"];
        commentvalidate 
= context.Request.Params["commentvalidate"];

        
if (action == "ajax_getcomment")
        {
            ajax_getcomment(id, Int32.Parse(page));
        }
        
else if (action == "ajax_sendcomment")
        {

            
//if (context.Session["VerifyCode"].ToString().ToLower() != commentvalidate.ToLower())
            
//{
            
//    //context.Request("ERROR!");
            
//    context.Response.Write("ERROR!");
            
//}
            
//else
            
//{
                DBQuery.ExecuteScalar("insert into comment(commentparentid,commentuser,commenttext,commentreply,commentip) values('" + commentparentid + "','" + commentuser + "','" + context.Server.HtmlEncode(commenttext) + "','','" + context.Request.ServerVariables["REMOTE_ADDR"+ "')");
            
//    context.Response.Write("评论发表成功!");
            
//}
        }
        
else
        {
            context.Response.Write(
"error!");
        }

    }

    
private void ajax_getcomment(string id, int page)
    {

        
using (CommentBO cm = new CommentBO(id, page - 1))
        {
            
            HttpContext.Current.Response.Write(cm.getCommentContent());
        }
    }
    
    
public bool IsReusable {
        
get 
        {
            
return false;
        }
    }

}