Suppose that I created a WebApi project using the latest ASP.NET 5 WebApi Visual Studio template. Now let's say that I create my own middleware class which creates its own HttpContext instances in order to indirectly send requests to the WebApi controller methods and get a response back; how could I do that and is it supported?
Below is my code attempt at doing this. If I call app.UseMvc() before app.UseMyMiddleware() I get a 404 response; but if I reverse those then I get a MVCNotRegisteredException when the worker thread calls await task.
The goal I am trying to accomplish essentially requires that in addition to receiving requests through the normal happy path (web server -> web app) that I have another socket that I control which receives HTTP requests and feeds them into the pipeline one way or another so that they get processed by the web app. The responses to those requests would be sent back out via that extra socket. If possible I would like to be able to do this while still using IIS and not forking Kestrel. Therefore, it seems if I could create a middleware component that read from the auxiliary socket, created a HttpContext and executed next.Invoke(context) then I could get what I am looking for. As an aside, do you expect that the HttpContext, HttpRequest, or HttpResponse abstract classes will be marked sealed at some point in the future, and/or will the DefaultHttpContext, DefaultHttpRequest, and DefaultHttpResponse classes be marked as private?
public class MyMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; public MyMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) { _next = next; _logger = loggerFactory.CreateLogger<MyMiddleware>(); ThreadPool.QueueUserWorkItem(async c => { var context = new DefaultHttpContext(); context.Request.Path = "/api/value/5"; context.Request.Method = "GET"; var task = Invoke(context); await task; var buffer = new byte[1024]; var body = context.Response.Body.Read(buffer, 0, 1024); var responseString = System.Text.Encoding.UTF8.GetString(buffer); _logger.LogInformation("Response: " + responseString); }); } public async Task Invoke(HttpContext context) { _logger.LogInformation("Handling request: " + context.Request.Path); await _next.Invoke(context); _logger.LogInformation("Finished handling request."); } }