我需要Web Api的帮助。
我正在建立一个多租户系统,当每个租户拥有自己的数据数据库时,首先使用代码EF和web api(这样我就可以创建多个应用程序平台)
我已将标准ASP.NET身份扩展为包含客户端ID和客户端模型,该模型将存储所有租户及其用户。
然后我创建了另一个跟踪每个租户存储的所有数据的上下文。
每个租户都拥有一个我需要根据经过身份验证的用户访问的数据库名称。
从每个api控制器获取用户ID似乎很简单:
RequestContext.Principal .....等然后我可以获取客户端,然后将客户端数据库名称传递给数据库上下文但是我正在尝试实现标准数据存储库模式,并且真的讨厌在代码中重复自己我认为目前正在运作的唯一方法是:
应用程序在授权后调用restful api Web Api捕获呼叫 每个端点都获取用户ID,并通过接口将其传递到数据存储,然后进入数据层,检索上下文的数据库名称。
我在这里遇到的问题是每个端点获取用户ID。有没有办法存储/跟踪"每个会话的用户ID?这可以通过范围依赖或类似的东西来实现吗?
我希望这是有道理的,但如果没有请问,我会进一步澄清,任何帮助将不胜感激。
由于
卡尔
答案 0 :(得分:1)
ASP WebApi没有会话上下文。您可以使用cookie或请求令牌标识符(从登录中传回此令牌,并将此令牌用作进一步API调用的参数)。
这是我不久前开发的东西。我只是创建一个派生自ApiController的新类,并且我使用这个类作为所有其他API类的基础。它使用可以通过HttpContext访问的ASP.NET缓存对象。我使用当前的用户ID作为参考。如果您还需要其他内容,可以使用其他方式缓存数据:
public abstract class BaseController: ApiController
{
private readonly object _lock = new object();
/// <summary>
/// The customer this controller is referencing to.
/// </summary>
protected Guid CustomerId
{
get
{
if (!_customerId.HasValue)
{
InitApi();
lock (_lock)
{
if (User.Identity.IsAuthenticated)
{
Guid? customerId = HttpContext.Current.Cache["APIID" + User.Identity.Name] as Guid?;
if (customerId.HasValue)
{
CustomerId = customerId.Value;
}
else
{
UserProfile user = UserManager.FindByName(User.Identity.Name);
if (user != null)
{
CustomerId = user.CustomerId;
HttpContext.Current.Cache["APIID" + User.Identity.Name] = user.CustomerId;
}
}
}
else
{
_customerId = Guid.Empty;
}
}
}
return _customerId.GetValueOrDefault();
}
private set { _customerId = value; }
}
// ... more code
}
不要责怪我在锁定&#34;东西。这段代码是某种&#34;启动并运行并忘记它&#34; ...
可以找到完整的示例here。
答案 1 :(得分:0)
也许我离真相很远,但Web API状态较差,所以你真的没有跟踪的会话