Предполагая, что вы работаете с asp. net mvc и со всем модным. net ядро промежуточного программного обеспечения еще не вещь, вы можете посмотреть на пользовательский handler
. Теоретически вы можете написать код bootstrap непосредственно в 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;
}
}
В зависимости от того, что именно вы хотите ваш обработчик, вы можете обнаружить, что вам также придется предоставить свою собственную 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 среде, так что это далеко не полное решение, но, надеюсь, оно очерчивает один путь для изучения