我想将所有请求的 URL(不包括来源)编码为 Base64。每当发出请求时,它都应该解码 URL,找到相应的 Controller 和操作,并使用相应的参数调用它。
是否有一个我可以覆盖的函数(可能在 global.asax
或 webapiconfig.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/