• 主页
  • ASP
  • .NET Framework
  • Web Services
  • VB
  • VC
  • 图表区
  • 分析与设计
  • 组件/控件开发
  • LINQ

.net core mvc参数反射

古耕 安徽游艺道网络科技有限公司 其他  2020-12-15 10:12:01
这边有个控制器,叫Api,控制器有个Action Rest接收所有Post方法,而所有请求中必须带入一个参数method,已知当路由直接定向控制器的时候,控制器的参数自动映射,但是当Rest收到请求时,根据method名称,获取私有方法中ActionName=method的方法,这时候需要将frombody里的参数反射成私有方法的参数对象,一般怎么做好?

private MethodInfo GetMethodInfo(string methodName)
{
if (string.IsNullOrEmpty(methodName)) return null;

MethodInfo method;
Methods.TryGetValue(methodName, out method);

return method;
}

[HttpPost]
public async Task<IActionResult> Rest(string method)
{
try
{
var methodfunc = GetMethodInfo(method);
if (methodfunc == null)
{
return Ok(new ApiReponse() { Code = "0001", Msg = $"method:" + method + " 不存在!" });
}

StreamReader bodyreader = new StreamReader(Request.Body);
var bodystr = await bodyreader.ReadToEndAsync();

var result = await (methodfunc.Invoke(this, new object[] {}) as Task<IActionResult>);
if (result == null)
{
return BadRequest(new ApiReponse() { Code = "0001", Msg = $"method:" + method + " 没有正常返回结果!" });
}



return result;
}
catch (Exception ex)
{
return BadRequest(new ApiReponse() { Code = "0001", Msg = $"调用接口异常:method:" + method + " 异常信息:" + ex.ToString() });
}
}

[ActionName("items.synchronize")]
private async Task<IActionResult> ItemsSynchronize([FromBody]ItemsSynchronizeRequest request)
{
try
{
return Ok(new ApiReponse()
{
Code = "9998",
Msg = "未知错误:"
});
}
catch (Exception ex)
{
return BadRequest(new ApiReponse()
{
Code = "9998",
Msg = "未知错误:" + ex.Message
});
}
}
...全文
6314 点赞 收藏 13
写回复
13 条回复
韩老骥 2020年12月17日
引用 4 楼 古耕 的回复:
动态调用以及方法寻找我这边是没问题的,但是自动反射参数这边不知道怎么做


方法信息里不是带了参数说明么,有类型、有名称、有顺序。
回复 点赞
wanghui0380 2020年12月17日
在来看他的路由和“万能模板” https://www.cnblogs.com/lcyhjx/p/12654565.html
回复 点赞
wanghui0380 2020年12月17日
另外这个东西其实也是那园子里现在死吹的一个“高级技术”----api网关 https://www.cnblogs.com/lcyhjx/p/12649936.html 来看他们的高级技术把,写了个配置文件把A转发到B,其实你想做的就是一样的东西,只是人家比你“高级”点,我外面架个代理网关,你里面该咋折腾就咋折腾,外面爱咋表现成统一就咋表现的好像是统一的
回复 点赞
wanghui0380 2020年12月17日
甚至在netcore下 app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapRest("/Rest"); }); endpoints.MapRest("/Rest"); 你可以写个中间件直接接管对/rest的中间访问,并插入到中间过程处理context,在自然转向到后续处理链条上
回复 点赞
正怒月神 2020年12月17日
反射的目的是什么? 创建一个类似路由中心的东西?
回复 点赞
wanghui0380 2020年12月17日
async Task<IActionResult> Rest(string method) 这东西怎么调用? Rest/xxx 或者是 rest?method=xxx so 这跟我直接定义路由为 [/Rest/id]有啥区别么
回复 点赞
wanghui0380 2020年12月17日
哎,被某园子来偏了。 来分析一下,你来反射,你来调用。ok,也就是你知道调用啥。 你凭啥知道调用啥?因为你有工厂,你有注入。 至于你说啥参数啥反射参数?一样一样的事情,凭啥是你反射参数?你知道对方要啥不? 所以完全偏离正轨,我们就问一句话,“凭啥我知道所有的方法,凭啥我知道所有方法应该需要知道哪些参数,既然我知道所有方法也知道需要知道哪些参数,那么又凭啥我要反射,我直接转换参数,直接call方法不行” 你既然要做万能api,就得假定你不是神仙,就得假定我只做转向不做调用,就得假定他自己做自己得事情俺们不参合 so,既然如此,你会发现你要做的是啥,当然是自定义路由,根据什么当路由。按你的规则那个方法名当路由的条件
回复 点赞
古耕 2020年12月17日
动态调用以及方法寻找我这边是没问题的,但是自动反射参数这边不知道怎么做
回复 点赞
wanghui0380 2020年12月17日
哎,也别说俺们光讲理论,不给代码。利用下班这点时间给你弄个例子 就用asp.net webapi默认的创建的项目,假设规定这么访问 https://localhost:44394/rest?method=weatherforecast.get 用.分隔controls和action 那么我们一个简单的demo可以是
   public void ConfigureServices(IServiceCollection services)
        {
           services.AddControllers();
            services.AddSingleton<TranslationTransformer>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            
            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {

                endpoints.MapDynamicControllerRoute<TranslationTransformer>("/Rest");
            });

            app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
            // app.UseAuthorization();

        }
  public class TranslationTransformer : DynamicRouteValueTransformer
    {
        public TranslationTransformer()
        {
            
        }
       
        public override async ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
        {
            var method = httpContext.Request.Query["method"];

            if (values == null)
                values = new RouteValueDictionary();

            string[] temp = method.First().Split('.');
            values["controller"]= temp[0];
            values["Action"] = temp[1];
            return values;
        }
    }
我们自己做个动态路由就好,你内部还是该怎么开发就怎么开发,外面用一个动态路由统一映射就好。下班15分钟了,我懒得折腾了,你看得懂自己完善。
回复 点赞
古耕 2020年12月17日
rest?method=xxx这样调用
回复 点赞
韩老骥 2020年12月16日
mvc本身就是基于反射的实现,通过拆分url匹配Controller类及其Action Method。你这不过是再套一层,估计是想动态调用BO层的方法,实现方式如#2楼所述,没什么滑头。
回复 点赞
Denuin 2020年12月16日

using System.Reflection;


Type t = this.GetType();
var m = t.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic);  // 找私有方法methodName
if(m != null)
{
  // 找到了
}
else
{
  // 没找到
}
回复 点赞
以专业开发人员为伍 2020年12月15日
除非必须,否则少用反射。如果对性能比较有要求,这往往会看到上百倍的性能差别。
回复 点赞
发动态
发帖子
.NET技术社区
创建于2007-09-28

4.9w+

社区成员

66.8w+

社区内容

.NET技术交流专区
社区公告
暂无公告