ASP.NET Web API-根据HTTP标头信息将正在运行的数据库应用程序更改为

本文关键字:运行 数据库 应用程序 API- Web NET 根据 HTTP 信息 ASP | 更新日期: 2023-09-27 18:19:59

我已经启动了一个新的Web API项目,该项目要求我们根据发送到API的HTTP头信息切换应用程序正在运行的数据库。应用程序用户将由HTTP标头标识,然后应用程序应更改为使用其数据库。

我有一个基本控制器CrudControllerBase<T>(用于处理简单的通用HTTP请求),它在其构造函数中创建了一个DataService<T>。我的所有控制器都将从这个基本控制器派生,并可以访问这个DataService。DataService用于执行常见的DB查询(FindById()、FindAll()等),而更复杂的查询则使用扩展方法进行绑定。

public abstract class CrudControllerBase<T> : ApiController where T : class, IEntity
{
    protected IDataService<T> _dataService;
    public CrudControllerBase()
    {
        this._dataService = new DataService<T>();
    }
    [HttpGet]
    public virtual async Task<IHttpActionResult> Get(Guid id)
    {
        var model = await _dataService.FindByIdAsync(id);
        return Ok<T>(model);
    }
    //code left out
}
public class OrdersController : CrudControllerBase<OrderItem>
    {
    }

在DataService中,我新建了DbContext类:

public class DataService<T> : IDataService<T> where T:class, IEntity
{
    private readonly AppDbContext _context;
    public DataService()
    {
        _context = new AppDbContext(); // need to pass in connection string
    }
    // code left out
}

我需要能够将连接字符串传递给AppDbContext的构造函数,但在CrudControllerBase的构造函数中,我没有访问HttpRequestMessage的权限,无法将此信息传递给DataService

有人能提出解决方案吗?如果有人能提出一些建议,我很乐意尝试一种完全不同的方式。谢谢

ASP.NET Web API-根据HTTP标头信息将正在运行的数据库应用程序更改为

好的,所以我已经开始工作了。这可能不是最好的解决方案,但它是有效的,如果有人有任何反馈/改进,请分享。感谢@AaronLS为我指明了正确的方向。这篇文章也帮助很大。

第一步是创建一个实现IHttpControllerActivator接口的CustomControllerFactory。这为您提供了一个Create方法,您可以在其中编写自己的代码来更新控制器。这是我的CustomControllerFactory,我在这里新建了我的控制器,将HTTP标头作为字符串传递:

public class CustomControllerFactory : IHttpControllerActivator
{
    public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        var schemaKey = request.Headers.Where(k => k.Key == "schema").FirstOrDefault().Value.FirstOrDefault();
        return (IHttpController)Activator.CreateInstance(controllerType, new string[] { schemaKey });
    }
}

下一步是告诉web API使用此方法来实例化控制器。为此,我在WebApiConfig类中添加了以下行:

GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new CustomControllerFactory());

我需要做的最后一件事是为每个控制器添加一个构造函数,该构造函数接收字符串值并将其传递给基本控制器

public OrdersController(String databaseName) : base(databaseName) { }

我的基地控制器将参数传递给DataService

public CrudControllerBase(String databaseName)
{
    this._dataService = new DataService<T>(databaseName);
}

并且我的数据库将连接字符串传递给AppDbContext()构造函数

public DataService(String databaseName)
{
    this._context = new AppDbContext(BuildConnectionString(databaseName));
}

我意识到还没有错误处理/安全检查,但我会在以下内容中添加:-)