有没有办法从我自己的应用程序中以编程方式调用ASP.NET Core请求管道,因为我有一个HTTP动词,路由,标题和正文有效负载?
在某些情况下,我们的ASP.NET Core应用程序的WebAPI无法访问,因为应用程序在防火墙后面运行或者无法访问。
要为此方案提供解决方案,我们希望我们的应用程序为"工作项"然后在我们的应用程序中转换为API调用。
Microsoft.AspNetCore.TestHost
包我可以创建TestClient
,这样我就可以向自己发出请求了(请参阅here)。但这里有一些不确定因素:
TestHost
的预期用例用于集成测试。在生产环境中使用它是否安全?TestServer
吗?TestClients
实例创建多个TestServer
并在不同的线程中使用它们吗?因此,我确信必须有一种更清晰,更直接的方式从我自己的应用程序中以编程方式调用请求管道...
答案 0 :(得分:1)
是的,实际上很容易。您可以在Startup类Configure方法的末尾获得对请求管道的引用。将其保存在静态字段/单例服务/等中。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ... usual configuration code
AClass.PipelineStaticField = app.Build();
}
然后,在您想要注入请求的方法中,必须构建一个HttpContext才能传递到管道中。
var ctx = new DefaultHttpContext();
// setup a DI scope for scoped services in your controllers etc.
using var scope = _provider.CreateScope();
ctx.RequestServices = scope.ServiceProvider;
// prepare the request as needed
ctx.Request.Body = new MemoryStream(...);
ctx.Request.ContentType = "application/json";
ctx.Request.ContentLength = 1234;
ctx.Request.Method = "POST";
ctx.Request.Path = PathString.FromUriComponent("/mycontroller/action");
// you only need this if you are hosting in IIS (.UseIISIntegration())
ctx.Request.Headers["MS-ASPNETCORE-TOKEN"] = Environment.GetEnvironmentVariable("ASPNETCORE_TOKEN");
// setup a place to hold the response body
ctx.Response.Body = new MemoryStream();
// execute the request
await AClass.PipelineStaticField(ctx);
// interpret the result as needed, e.g. parse the body
ctx.Response.Body.Seek(0, SeekOrigin.Begin);
using var reader = new StreamReader(ctx.Response.Body);
string body = await reader.ReadToEndAsync();
这样,您的请求将遍历整个管道,包括所有中间件,例如身份验证和授权。