c# - 覆盖 .net Web API 中操作映射和参数的基本功能

标签 c# .net asp.net-web-api

我想将所有请求的 URL(不包括来源)编码为 Base64。每当发出请求时,它都应该解码 URL,找到相应的 Controller 和操作,并使用相应的参数调用它。

是否有一个我可以覆盖的函数(可能在 global.asaxwebapiconfig.cs 中),每当发出请求时都会调用该函数?

最佳答案

假设您使用 asp.net mvc 并且所有花哨的 .net core 中间件还不是一件事,您可以查看自定义 handler 。 理论上,您可以直接在 global.asax 中编写引导代码,但默认情况下它会调用 WebApiConfig.Register():

 GlobalConfiguration.Configure(WebApiConfig.Register);

这可能是处理 WebAPI 的更好地方。

App_Start/WebApiConfig.cs

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            // Web API routes
            config.MessageHandlers.Add(new TestHandler()); // if you define a handler here it will kick in for ALL requests coming into your WebAPI (this does not affect MVC pages though)
            config.MapHttpAttributeRoutes();
            config.Services.Replace(typeof(IHttpControllerSelector), new MyControllerSelector(config)); // you likely will want to override some more services to ensure your logic is supported, this is one example

            // your default routes
            config.Routes.MapHttpRoute(name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new {id = RouteParameter.Optional});

            //a non-overlapping endpoint to distinguish between requests. you can limit your handler to only kick in to this pipeline
            config.Routes.MapHttpRoute(name: "Base64Api", routeTemplate: "apibase64/{query}", defaults: null, constraints: null
                //, handler: new TestHandler() { InnerHandler = new HttpControllerDispatcher(config) } // here's another option to define a handler
            );
        }
    }

然后定义您的处理程序:

TestHandler.cs

    public class TestHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            //suppose we've got a URL like so: http://localhost:60290/api/VmFsdWVzCg==
            var b64Encoded = request.RequestUri.AbsolutePath.Remove(0, "/apibase64/".Length);
            byte[] data = Convert.FromBase64String(b64Encoded);
            string decodedString = Encoding.UTF8.GetString(data); // this will decode to values
            request.Headers.Add("controllerToCall", decodedString); // let us say this is the controller we want to invoke
            HttpResponseMessage resp = await base.SendAsync(request, cancellationToken);
            return resp;
        }
    }

根据您希望 Handler 执行的具体操作,您可能会发现您还必须提供自定义 ControllerSelector 实现:

WebApiConfig.cs

// add this line in your Register method
config.Services.Replace(typeof(IHttpControllerSelector), new MyControllerSelector(config));

MyControllerSelector.cs

    public class MyControllerSelector : DefaultHttpControllerSelector
    {
        public MyControllerSelector(HttpConfiguration configuration) : base(configuration)
        {
        }

        public override string GetControllerName(HttpRequestMessage request)
        {
            //this is pretty minimal implementation that examines a header set from TestHandler and returns correct value
            if (request.Headers.TryGetValues("controllerToCall", out var candidates))
                return candidates.First();
            else
            {
                return base.GetControllerName(request);
            }
        }
    }

我对您的具体环境了解不够,因此这远不是完整的解决方案,但希望它概述了您探索的一种途径

关于c# - 覆盖 .net Web API 中操作映射和参数的基本功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59643701/

相关文章:

c# - WebApi 2 中 IHostBufferPolicySelector 上下文中的空 RouteData

c# - 将字典序列化为json文件

c# - 之后如何应用gitignore?

c# - 如何获取 WPF 应用程序的默认路径数据库位置?

c# - 使用指令的冗余

.net - 用于设置 CurrentCulture 的线程创建事件

asp.net-web-api - 找不到与 ASP.NET Web API 中的请求 URI 错误匹配的 HTTP 资源

c# - 为什么这个 web api Controller 不是并发的?

javascript - 在 Angularjs 中通过 IP 地址获取用户的位置

c# - 应用程序配置 : custom configuration nested sections