这里分几种情况来讨论。(这里测试环境为.net 4.0 IIS7 Win7)
一、自定义HttpHandler类中请求aspx、ashx、自定义HttpHandler类
首先Web.congfig中配置自定义处理程序
1、自定义HttpHandler类使用Server.Execute跳转到Page页
public class MyHttpHandler:IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
StringWriter sw = new StringWriter();
context.Server.Execute("/SelfTextBoxControlTest.aspx",sw,false);
string dealResult = sw.ToString();
context.Response.Write(dealResult);
context.Response.End();
}
}
尝试解决方案:
HttpHandler类继承Page类
代码:
public class MyHttpHandler:Page
{
public override void ProcessRequest(HttpContext context)
{
StringWriter sw = new StringWriter();
context.Server.Execute("/SelfTextBoxControlTest.aspx",false);
string dealResult = sw.ToString();
context.Response.Write(dealResult);
context.Response.End();
}
}
运行时虽然不报“执行子请求出错”,但一直循环调用ProcessRequest方法,形成死循环
解决方案:
MyHttpHandler继承IHttpHandler(继承Page也可以),通过BuildManager.CreateInstanceFromVirtualPath方法获取页面的IHttpHandler实例,再将该实例传入Execute重载方法(public void Execute(IHttpHandler handler, TextWriter writer, bool preserveForm))中
代码:
public class MyHttpHandler:IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
StringWriter sw = new StringWriter();
var handler = BuildManager.CreateInstanceFromVirtualPath("/SelfTextBoxControlTest.aspx", typeof(IHttpHandler)) as IHttpHandler;
context.Server.Execute(handler,sw,false);
string dealResult = sw.ToString();
context.Response.Write(dealResult);
context.Response.End();
}
}
2、自定义HttpHandler类使用Server.Execute跳转到ashx一般处理程序中
代码:
public class MyHttpHandler:IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
StringWriter sw = new StringWriter();
context.Server.Execute("/CommonHandler2.ashx", sw, false);
string dealResult = sw.ToString();
context.Response.Write(dealResult);
context.Response.End();
}
}
那是不是和请求page页面一样,用BuildManager.CreateInstanceFromVirtualPath()就能解决呢?我们来试一下
代码:
public class MyHttpHandler:IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
StringWriter sw = new StringWriter();
var handler = BuildManager.CreateInstanceFromVirtualPath("/CommonHandler2.ashx", typeof(IHttpHandler)) as IHttpHandler;
context.Server.Execute(handler, sw, false);
string dealResult = sw.ToString();
context.Response.Write(dealResult);
context.Response.End();
}
}
说明请求ashx和aspx页面不同,我们来试试将ashx文件类继承Page
代码:
<%@ WebHandler Language="C#" Class="CommonHandler2" %>
using System;
using System.Web;
using System.Web.UI;
public class CommonHandler2 :Page{
public override void ProcessRequest (HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Write("Hello World");
}
}
在将ashx文件类继承Page类后,其实用
context.Server.Execute("/CommonHandler2.ashx", sw, false);
同样不会报错,正常执行
。
3、自定义HttpHandler类使用Server.Execute跳转到其他自定义的HttpHandler类
代码:
MyHttpHandler
public class MyHttpHandler:IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
StringWriter sw = new StringWriter();
TestHandler handler = new TestHandler();
context.Server.Execute(handler, sw, false);
string dealResult = sw.ToString();
context.Response.Write(dealResult);
context.Response.End();
}
}
TestHandler
public class TestHandler:IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.Write("TestHandler");
}
}
运行代码,报“执行子请求错误”。
解决方案:
在目标请求类TestHandler继承改为Page类,即:
TestHandler
public class TestHandler:Page
{
public override void ProcessRequest(HttpContext context)
{
context.Response.Write("TestHandler");
}
}
运行代码,正常执行!
二、Asp.Net Page页中请求其他Page页、ashx文件、自定HttpHandler类
1、Asp.Net Page页中请求其他Page页
代码:
public partial class _Default : Page
{
protected void btnTestHandler_Click(object sender, EventArgs e)
{
StringWriter sw = new StringWriter();
Context.Server.Execute("/SelfTextBoxControlTest.aspx", sw, false);
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
运行代码,一切正常!说明Page页调用其他Page页,只需将目标文件路径传入Server.Execute中即可,当然,通过CreateInstanceFromVirtualPath获取文件实例再传入也行。
2、Asp.Net Page页中请求ashx文件
这种情况和上面自定义HttpHandler类请求ashx文件一样,ashx文件类也必须继承Page类才能正常被请求,否则报“执行子请求出错”
3、Asp.Net Page页中请求自定义HttpHandler类
这种情况和上面自定义HttpHandler类请求其他自定义HttpHandler类一样,被请求的自定义HttpHandler类也必须继承Page类才能正常被请求,否则报“执行子请求出错”
至于内部原理,暂时还没搞清楚,等以后弄明白后后续再更新博文。有知道的朋友可以给我留言,万分感谢!