Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Web Api用户跟踪_C#_Asp.net_Entity Framework_Api - Fatal编程技术网

C# Web Api用户跟踪

C# Web Api用户跟踪,c#,asp.net,entity-framework,api,C#,Asp.net,Entity Framework,Api,我需要Web Api方面的帮助 我正在建立一个多租户系统,每个租户都有自己的数据数据库,使用代码优先EF和web api(这样我就可以创建多个应用程序平台) 我已经扩展了标准ASP.NET标识,以包括一个客户端id和客户端模型,该模型将存储所有租户及其用户 然后,我创建了另一个上下文,它跟踪每个租户存储的所有数据 每个租户都拥有一个数据库名称,我需要根据经过身份验证的用户访问该名称 不从每个api控制器获取用户id似乎很容易: RequestContext.Principal。。。。。等等,然后

我需要Web Api方面的帮助

我正在建立一个多租户系统,每个租户都有自己的数据数据库,使用代码优先EF和web api(这样我就可以创建多个应用程序平台)

我已经扩展了标准ASP.NET标识,以包括一个客户端id和客户端模型,该模型将存储所有租户及其用户

然后,我创建了另一个上下文,它跟踪每个租户存储的所有数据

每个租户都拥有一个数据库名称,我需要根据经过身份验证的用户访问该名称

不从每个api控制器获取用户id似乎很容易:

RequestContext.Principal。。。。。等等,然后我可以将客户机和随后的客户机数据库名称传递到数据库上下文,但是我正在尝试实现一个标准的数据存储库模式,非常讨厌在代码中重复我自己,但目前我看到它工作的唯一方式是:

应用程序在授权后调用restful api Web Api捕获调用 每个端点获取用户id,并通过接口将其传递到数据存储,然后再传递到数据层,检索上下文的数据库名称

我在这里遇到的问题是每个端点都获取用户id。是否有一种方法可以“存储/跟踪”每个会话的用户id?这可以通过范围依赖或类似的方式实现吗

我希望这是有道理的,但如果没有请问,我会试图进一步澄清,任何帮助将不胜感激

谢谢


Carl

ASP WebApi没有会话上下文。您可以使用cookie或请求令牌标识符(将此令牌从登录中传递回,并将此令牌用作进一步API调用的参数)

这是我很久以前开发的东西。我只是创建一个从ApiController派生的新类,并将该类用作所有其他API类的基础。它使用ASP.NET缓存对象,可以通过HttpContext访问该对象。我正在使用当前用户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
}
公共抽象类BaseController:ApiController
{
私有只读对象_lock=新对象();
/// 
///此控制器所引用的客户。
/// 
受保护的Guid客户ID
{
得到
{
如果(!\u customerId.HasValue)
{
InitApi();
锁
{
if(User.Identity.IsAuthenticated)
{
Guid?customerId=HttpContext.Current.Cache[“apid”+User.Identity.Name]作为Guid?;
if(customerId.HasValue)
{
CustomerId=CustomerId.Value;
}
其他的
{
UserProfile user=UserManager.FindByName(user.Identity.Name);
如果(用户!=null)
{
CustomerId=user.CustomerId;
HttpContext.Current.Cache[“apid”+User.Identity.Name]=User.CustomerId;
}
}
}
其他的
{
_customerId=Guid.Empty;
}
}
}
返回_customerId.GetValueOrDefault();
}
私有集{u customerId=value;}
}
//…更多代码
}
别把“锁”的事怪我。这段代码是某种“启动并运行,然后忘记它”


一个完整的例子可以找到。

也许我说的不是事实,但是Web API没有状态,所以你没有真正的会话可以跟踪。

嗨,Stephen,谢谢你回到我这里来。我知道没有会话上下文,但想知道是否有一种方法可以将RequestContext抽象为一个泛型类,我可以调用它在一个地方获取用户id、客户端和db名称,而不是在每个端点中编写相同的代码。也许我没有抓住要点,或者根本不明白(如果是这样的话,很抱歉)。嗨,我添加了一些示例代码。我是从一个真实的应用程序中提取出来的,这意味着:1。它有效:-)2。如果没有更改,它将无法在您这边编译:-(嗨!这太完美了,谢谢您回到我这里,这正是我所需要的。