使用中间件注入路由数据
Inject route data using middleware
我正在构建一个非常简单的 rest api。我在特定控制器下的所有端点都需要一个 QueryContext 类型的对象。此对象是 HttpRequest 的 "simplified" 版本。
目前,我使用工厂接受 HttpRequest 并返回 QueryContext 类型的对象。
public interface IQueryContextFactory
{
QueryContext Create(string query, HttpRequest request);
}
internal class HttpRequestQueryContextFactory : IQueryContextFactory
{
public QueryContext Create(string query, HttpRequest request)
{
if (string.IsNullOrEmpty(query))
throw new ArgumentNullException(nameof(query));
if (request == null)
throw new ArgumentNullException(nameof(request));
return new QueryContext
{
Method = request.Method,
QueryString = string.Concat(query, request.QueryString),
Parameters = request.Query.ToDictionary(x => x.Key, x => x.Value.ToString().Replace("\"", string.Empty)),
Headers = request.Headers.ToDictionary(x => x.Key, x => x.Value.ToString())
};
}
}
然后我从我的端点调用这个工厂
[HttpGet]
public IActionResult Process(string query)
{
(...)
var ctx = _contextFactory.Create(query, Request);
}
是否推荐使用中间件将QueryContext 添加到路由数据中?这个我能把它作为参数吗?
您可以在 API 控制器中注入一个 IQueryContextFactory。
这是一个例子:
[Route("api/my")]
public class MyController : Controller {
private readonly IQueryContextFactory QueryContextFactory;
public MyController(IQueryContextFactory queryContextFactory) {
if (queryContextFactory == null)
throw new ArgumentNullException(nameof(queryContextFactory));
QueryContextFactory = queryContextFactory;
}
[HttpGet]
public IActionResult Get(string query) {
var ctx = QueryContextFactory.Create(query, Request);
return Ok();
}
}
然后,您在 Startup.cs
中配置注入,如下所示:
public void ConfigureServices(IServiceCollection services) {
//...
services.AddSingleton<IQueryContextFactory, HttpRequestQueryContextFactory>();
//...
}
您可以找到有关注入的更多信息here。
如您所示,简化的 QueryContext class 中的所有数据也在 HttpContext 中。您可以做一些不同的事情,而不是将另一个对象注入您的控制器。
初始化 QueryContext 属性 或输入控制器的构造函数。这样它就可以用于所有控制器方法而无需重复代码。
而是添加一个新的 class extend HttpContext class 以及一些可以满足您需要的扩展方法。
我正在构建一个非常简单的 rest api。我在特定控制器下的所有端点都需要一个 QueryContext 类型的对象。此对象是 HttpRequest 的 "simplified" 版本。
目前,我使用工厂接受 HttpRequest 并返回 QueryContext 类型的对象。
public interface IQueryContextFactory
{
QueryContext Create(string query, HttpRequest request);
}
internal class HttpRequestQueryContextFactory : IQueryContextFactory
{
public QueryContext Create(string query, HttpRequest request)
{
if (string.IsNullOrEmpty(query))
throw new ArgumentNullException(nameof(query));
if (request == null)
throw new ArgumentNullException(nameof(request));
return new QueryContext
{
Method = request.Method,
QueryString = string.Concat(query, request.QueryString),
Parameters = request.Query.ToDictionary(x => x.Key, x => x.Value.ToString().Replace("\"", string.Empty)),
Headers = request.Headers.ToDictionary(x => x.Key, x => x.Value.ToString())
};
}
}
然后我从我的端点调用这个工厂
[HttpGet]
public IActionResult Process(string query)
{
(...)
var ctx = _contextFactory.Create(query, Request);
}
是否推荐使用中间件将QueryContext 添加到路由数据中?这个我能把它作为参数吗?
您可以在 API 控制器中注入一个 IQueryContextFactory。
这是一个例子:
[Route("api/my")]
public class MyController : Controller {
private readonly IQueryContextFactory QueryContextFactory;
public MyController(IQueryContextFactory queryContextFactory) {
if (queryContextFactory == null)
throw new ArgumentNullException(nameof(queryContextFactory));
QueryContextFactory = queryContextFactory;
}
[HttpGet]
public IActionResult Get(string query) {
var ctx = QueryContextFactory.Create(query, Request);
return Ok();
}
}
然后,您在 Startup.cs
中配置注入,如下所示:
public void ConfigureServices(IServiceCollection services) {
//...
services.AddSingleton<IQueryContextFactory, HttpRequestQueryContextFactory>();
//...
}
您可以找到有关注入的更多信息here。
如您所示,简化的 QueryContext class 中的所有数据也在 HttpContext 中。您可以做一些不同的事情,而不是将另一个对象注入您的控制器。
初始化 QueryContext 属性 或输入控制器的构造函数。这样它就可以用于所有控制器方法而无需重复代码。
而是添加一个新的 class extend HttpContext class 以及一些可以满足您需要的扩展方法。