我在HttpHandler中,拦载了一个请求,并通过请求送过来的url,分解出对象,方法,参数三项。
通过反射调用对象的方法,并把参数绑定进去执行,然后返回结果。
现在的问题是,参数怎么绑定。方法的参数有可能是int,string,object...
mvc中是自带有ModelBinder这样的机制来做数据绑定的,我现在就是想怎么把这套机制拿过来用。
只是他反射的是控制器的方法,参数,而我是要反射我定义对象的方法,参数。
有没有高人能给我指点一下。不胜感激。
附代码片段:public class AjaxHttpHandler : IHttpHandler 
{
  public AjaxHttpHandler() { }
  public void ProcessRequest(HttpContext context) 
  {
    //截掉路径中第一个"/"字符,截掉尾的".ajax",通过"/"分隔,得到对象的名称及方法
    var strObjact = context.Request.Path.Substring(1, context.Request.Path.Length-6).Split('/');
    //使用无参数构造函数创建对象
    var asm = System.Reflection.Assembly.GetExecutingAssembly();
    Object obj = asm.CreateInstance("sqerp.BusinessModels." + strObjact[0], false);    Type t = obj.GetType();
    var param = //就是这里了,怎么绑定这个参数...
    var result = t.InvokeMember(strObjact[1], System.Reflection.BindingFlags.InvokeMethod, null, obj, param);
  }
}mvcModelBinder

解决方案 »

  1.   

    反射拿到methodInfo,通过方法名去匹配
      

  2.   

        //数据绑定,根据传入参数,获取调用对象的方法参数做绑定,如果对象方法参数是对象,生成此对象并附值
        //简化功能,只绑定值类型,对象的绑定后期再加吧,关键字:DefaultModelBinder,http://www.cnblogs.com/niuchenglei/archive/2010/03/12/1684683.html#title3
        public class ParamBinder
        {
            public static object[] AutoBind(string source,System.Reflection.ParameterInfo[] paramInfo)
            {
                if (paramInfo.Count() == 0) return null;
                var paramObj = source.Split('&').Select(a => new { key = a.Substring(0, a.IndexOf('=')), value = a.Substring(a.IndexOf('=') + 1) }).ToList();
                Object[] param = new Object[paramInfo.Count()];
                int i =0;
                foreach (var item in paramInfo)
                {
                    string value = source.Split('&').Where(a => a.StartsWith(item.Name + '=')).Single().Substring(item.Name.Length + 1);
                    if (!item.ParameterType.IsClass)
                    {
                        param[i] = item.ParameterType.InvokeMember("Parse", System.Reflection.BindingFlags.InvokeMethod, null, null, new object[] { value });
                    }
                    else if(item.ParameterType.Name=="String")
                    {
                        param[i] = value;
                    }
                    i++;            }
                return param;
            }
        }>>目前的这个问题已经解决了,虽然是只绑值类型的,其实是对象的,也可以做到,只是我担心效率更想用系统提供的,
    调用:
    var param = ParamBinder.AutoBind(strParam, t.GetMethod(strObjact[1]).GetParameters());
      

  3.   

    其实总体的思路非常简单,因为mvc的调用是 请求 到控制器, 控制器调用业务类方法返回模型,模型绑到视图返回。但因为我用的全是异步,不存在视图的问题,我只要返回的json,而控制器里只做个权限的校验和调用业务模型,所以我就把请求拦截省掉控制器,直接找方法返回json。所以要用反射。做了路由的事。
      

  4.   

    哦, 明白你的需求了。 不过你可以用jquery的ajax 直接调用 action, 不需要自己写路由
    $.ajax({ url: '/Controller/Action/Id',
             success: function(data) { alert(data); }, 
             statusCode : {
                 404: function(content) { alert('cannot find resource'); },
                 505: function(content) { alert('internal server error'); }
             }, 
             error: function(req, status, errorObj) {
                   // handle status === "timeout"
                   // handle other errors
             }
    });
    另外可返回json格式
      

  5.   


    呵呵,看到这里我笑了,唉,无语。就我这临时被公司抓包过来搞了一个星期所谓的asp.net mvc滴人都知道,除了ActionResult 还有JsonResult,你何必做那么多余的事情。更何况mvc4里还有webapi提供
      

  6.   


    >>你这么说是根本没有看懂我最想省掉就是控制器,我所有的业务操作都是在类中,控制器仅调用,如User下有Add(),Edit()等等方法,则控制器就是一个调用,return Json(User.add()),如果我有10个,20个业务的操作,那我要生成相对应的控制器,这下你懂了为什么不要用JsonResult了吗,先把别人的需求搞清楚。谢谢!
      

  7.   

    好了回到你的问题,非要如此可以不可以,其实也可以不过嘛,基本上也是一个故事像你非要用反射,你可以遍历属性(查找属性名,获得属性的类型和构造,然后根据类型convert后在反射赋值),遍历方法(查找最符合的方法签名,在遍历参数方法,把参数convert成需要的类型反射调用)说白了,其实还是一个故事,你是要根据对象元数据推论,而我们则说推论不是很必要,我想声明就手动注册声明一下,免掉复杂的推论过程。其实路由表 和控制器的存在,原本就是为了省掉这种复杂的签名推论过程而设计的
      

  8.   

    www.xxx.com/user/add?name='x'&age=24
    反射找到user的add方法,并把参数绑上去,权限验证,执行,返回json。
    有多少业务类,就能省多少控制器,也免得维护,通过在user类与方法上挂特性,直接生成多级的权限树,如果是控制器的,就只能做两层,不然就要再多一次界面去做多层的维护...
    所以,我要的不仅仅是省一个控制器,而是配合着我自己的一套方法在运行。
      

  9.   


    >>这里的省掉,实际上只是我们不用写代码而已,而是微软通过与我一样的判断逻辑做了这样的反射,找到控制器。但不是说这样的模式我就完全不用了,而是仅因为我ajax的操作方法过于一致,所以不想再维护控制器与业务方法的关系而做的努力。不论如何,还是感谢你花出时间帮我做的分析。
      

  10.   

    微软做的事情,跟你想象的并不一样,这个推论过程他不是在运行期做的他其实是在编译期就在做这个事情。在编译期他就会根据路由表CodeDom或emit 生成一个你看不见的对象,所有分解参数,转换类型,传递参数都在这个你看不见的对象里面。