using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO;
using System.Web.UI;
namespace MyClass
{
public class MyHttpHandlerFactory:IHttpHandlerFactory
{
#region IHttpHandlerFactory 成员
///<summary>
/// 返回实现 System.Web.IHttpHandler 接口的类的实例
///</summary>
///<param>System.Web.HttpContext 类的实例,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session和 Server)的引用</param>
///<param>客户端使用的 HTTP 数据传输方法(GET 或 POST)</param>
///<param>所请求资源的 System.Web.HttpRequest.RawUrl</param>
///<param>所请求资源的 System.Web.HttpRequest.PhysicalApplicationPath</param>
///<returns>处理请求的新的 System.Web.IHttpHandler 对象</returns>
public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
List<string> qeryString;
string virtualPath;
string inputFile =MyHttpModule.GetInputFile(context, out virtualPath, out qeryString);//这里跟那里是一样的
object[] obj = new object[] { };
Dictionary<string, string> qeryStringDictionary = new Dictionary<string, string>();
var receiveMembers = System.Web.Compilation.BuildManager.GetCompiledType(virtualPath).GetMember("ReceiveParameters");//获取访问当前页面的所有ReceiveParameters成员 (这个是我自己加的,就是想做成和mvc的那种模式,但可能不是很好)
System.Reflection.MethodInfo receiveParameters=null;
if (qeryString != null&&qeryString.Count>0)//如果查找到没有参数则不去反射了
{
foreach (System.Reflection.MemberInfo receiveMember in receiveMembers)//遍历所有ReceiveParameters成员
{
if (receiveMember.MemberType == System.Reflection.MemberTypes.Method)//因为上面获取到的是成员 但我们要的是方法所有要判断下
{
System.Reflection.MethodInfo methodInfo = receiveMember as System.Reflection.MethodInfo;
if (methodInfo != null)
{
var parameters = methodInfo.GetParameters();//获取ReceiveParameters方法的所有参数
int optionalCount = parameters.Count(i => i.IsOptional);//获取ReceiveParameters参数里面有多少个可选参数
bool b = qeryString.Count == parameters.Length - optionalCount;
if (qeryString.Count == parameters.Length || b)//如果当前查询的参数或ReceiveParameters的所有参数-去可选择的查询参数相等
{
receiveParameters = methodInfo;//记录这个方法
int i = 0;
obj = new object[parameters.Length];//记录参数值,到后面调用ReceiveParameters时用
for (; i < parameters.Length; i++)
{
string name = parameters[i].Name;//获取参数的名称
string value = string.Empty;
if (qeryString.Count > i)//如果ReceiveParameters参数没到可选参数那么则去查询的字符串
{
value = qeryString[i];
}
obj[i] = value;//把查询的字符串保存起来,到后面调用ReceiveParameters时用
qeryStringDictionary.Add(name, value);//添加到自定义的集合里面
}
break;
}
}
}
}
if (receiveParameters == null)//判断是否已经找到,如果没找到就把以前找的文件信息全部赋为重写的文件信息,也就是不存在的
{
virtualPath = context.Request.Path;
inputFile = context.Request.PhysicalPath;
}
}
var temp= System.Web.UI.PageParser.GetCompiledPageInstance(virtualPath, inputFile, context);//编译页面
if (receiveParameters != null)//这个里面的内容其实应该写到ReleaseHandler里面去的,但我写在这里了
{
System.Web.UI.Page page = (System.Web.UI.Page)temp;
page.Init+=new EventHandler(page_Init);//添加一个事件 ,//还有就是本来应该添加一个PageBase类的,那样就可以把真实的路径信息和查询参数放进去
sss = receiveParameters;
sssobj = obj;
//receiveParameters.Invoke(temp, obj);
}
return temp;
}
public System.Reflection.MethodInfo sss { get; set; }
public object[] sssobj { get; set; }
protected void page_Init(object sender, EventArgs e)
{
sss.Invoke(sender, sssobj);//当page执行到这里时就去调用ReceiveParameters方法 在这里还可以做其它的判断。。。 但不符合编程规范(我的理解)
}
///<summary>
/// 使工厂可以重用现有的处理程序实例
///</summary>
///<param>要重用的 System.Web.IHttpHandler 对象</param>
public void ReleaseHandler(IHttpHandler handler)
{
}
#endregion
}
}
页面代码就是多放几个方法
///<summary>
/// 一个参数的 如果需要多个则手动添加如public void ReceiveParameters(string name,string value)等等 这样页面编译后就会根据参数自动运行这个方法并转递参数值
///</summary>
///<param>参数名称为name</param>
public void ReceiveParameters(string name)
{
var temp = Request;
}
url的解决了,在来看看干掉试图的。。。
我只写了把事件的实体状态去掉了,然后手动去激发控件的事件,而且就是在url中写里面解决的 代码如下:
复制代码 代码如下: