对于以上的ashx,我们需要在web项目中,新建一个名为BLLAshx的ashx文件,但是我们不要.cs的文件,并作如下修改:
<%@ WebHandler Language="C#" CodeBehind="BLLAshx.cs" Class="Common.BLLAshx" %>
现在我们再次回到ajax调用的地方,大家都会发现我们的参数列表室在太长了,因此大家可能会想用一些方法来改善,比如:连ashx都懒的重复去写了,想直接在url中把弥命名空间、类、方法直接放进去来替代,想到这一步的时候,我们就需要配置web.config了,假设我们想要的规则是SysBLL/SysBLL.CustomerBLL.Search,配置如下:
<httpHandlers>
<add path="*/*.*.*.do" type="Common.BLLAshx" verb="GET,POST"/>
</httpHandlers>
有人会问为什么这边要.do,而不直接省略呢?因为如果不加.do,那么就会将其他的请求也都转向我们的ashx,例如:js、css文件等,大家可以自己测试看看.因为我们使用了地址映射,因此我们的js以及ashx代码又要做一些改动了.大致修改如下:
//ashx
namespace Common
{
public class BLLAshx : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string assemblyName = context.Request.QueryString["assemlby"], fullName = context.Request.Params["fullName"];
var bllType = Assembly.Load(assemblyName).GetType(fullName);
var methodName = context.Request.Params["method"];
var method = bllType.GetMethod(methodName);
if (null != method)
{
string[] parameterValues = GetMethodParameterValues(context.Request, method);
var instance = Activator.CreateInstance(bllType);
var result = method.ReturnType == typeof(void) ? "{}" : method.Invoke(instance, parameterValues).ToString();
//以上Invoke省略了判断以及捕捉异常
context.Response.Write(result);
}
else
{
//返回不存在方法的提示
}
}
private string[] GetMethodParameterValues(HttpRequest request, MethodInfo method)
{
string[] parameterValues = null;
var methodParameters = method.GetParameters();
if (0 < methodParameters.Length)
{
parameterValues = new string[methodParameters.Length];
for (int i = 0; i < methodParameters.Length; i++)
{
parameterValues[i] = request.Params[methodParameters[i].Name];
}
}
return parameterValues;
}
}
}
//CustomerBLL
namespace SysBLL
{
public class CustomerBLL
{
public string Search(string name)
{
var json = ...//获取数据
return json;
}
}
}
ashx的调整,我们只要修改ProcessRequest方法,代码大致如下:
var reg = new Regex(@"(?<assembly>\w+)\/(?<class>\w+\.\w+)\.(?<method>\w+)\.");
var groups = reg.Match(context.Request.AppRelativeCurrentExecutionFilePath).Groups;
if (4 == groups.Count)
{
string assemblyName = groups["assembly"].Value, fullName = groups["class"].Value;
var bllType = Assembly.Load(assemblyName).GetType(fullName);
var methodName = groups["method"].Value;
var method = bllType.GetMethod(methodName);
if (null != method)
{
string[] parameterValues = GetMethodParameterValues(context.Request, method);
var instance = Activator.CreateInstance(bllType);
var result = method.ReturnType == typeof(void) ? "{}" : method.Invoke(instance, parameterValues).ToString();
//以上Invoke省略了判断以及捕捉异常
context.Response.Write(result);
}
else
{
//返回不存在方法的提示
}
}
else
{
//url匹配不正确
}
有人可能会问为什么要重复SysBLL/SysBLL呢?其实可以省略其中的一个,但是条件是程序集必须要跟这个前缀一样才能省略.
如果大家想要省略其中一次SysBLL,那么正则的匹配规则也要相应的调整一下,只要将(?<class>\w+.\w+)中的.\w+去掉即可.
大致的实现流程就到这里了,我们已经将大部分的需求基本完成了,还有一些遗留的问题留给大家去完善啦,比如:调用的方法参数必须都是string类型,方法的返回值也必须要是string类型,反射的类不能是泛型类型的等等.
转自 https://www.cnblogs.com/ahl5esoft/archive/2012/06/27/2565496.html