.net core mvc参数反射

石岩Maple 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
});
}
}
...全文
6577 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
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,既然如此,你会发现你要做的是啥,当然是自定义路由,根据什么当路由。按你的规则那个方法名当路由的条件
石岩Maple 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分钟了,我懒得折腾了,你看得懂自己完善。
石岩Maple 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
{
  // 没找到
}
  • 打赏
  • 举报
回复
除非必须,否则少用反射。如果对性能比较有要求,这往往会看到上百倍的性能差别。

62,243

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧