C# 静态委托如何访问非静态、服务器端、基于会话的信息?
关于标题,我很抱歉。这相当复杂。我将尝试用一种简化、抽象的方式(尽可能多地)对其进行总结 在web表单应用程序中,DAL将在两种不同的上下文中使用:C# 静态委托如何访问非静态、服务器端、基于会话的信息?,c#,asp.net,session,data-access-layer,C#,Asp.net,Session,Data Access Layer,关于标题,我很抱歉。这相当复杂。我将尝试用一种简化、抽象的方式(尽可能多地)对其进行总结 在web表单应用程序中,DAL将在两种不同的上下文中使用: 从代码隐藏 来自Web API控制器 在每次调用中,需要让DAL知道当前用户Id,以便它可以根据数据库事务存储此Id。我已经向DAL添加了一个Func类型的静态属性,这样当使用DAL时,可以为它提供一个方法(通过调用代码),允许它获取用户id 从代码隐藏进行的调用将提供一个GetUserId方法,该方法从会话中获取用户id,而Web API控制器调
class Program
{
static void Main(string[] args)
{
for (var i = 0; i < 10; i++)
StartTestThread(i);
Console.ReadKey();
}
private static void StartTestThread(int i)
{
Thread.Sleep(2000);
ThreadPool.QueueUserWorkItem(delegate {
Console.WriteLine(string.Format("[{0}] Setting context...", i));
SetCallContext(i);
Console.WriteLine(string.Format("[{0}] Waiting...", i));
Thread.Sleep(5000);
Console.WriteLine(string.Format("[{0}] Context is {1}", i, GetCallContext()));
});
}
private static void SetCallContext(int i)
{
CallContext.LogicalSetData("Test", i);
}
private static int GetCallContext()
{
return (int) CallContext.LogicalGetData("Test");
}
}
类程序
{
静态void Main(字符串[]参数)
{
对于(变量i=0;i<10;i++)
starttsethread(i);
Console.ReadKey();
}
私有静态void starttesthread(int i)
{
《睡眠》(2000年);
ThreadPool.QueueUserWorkItem(委托{
WriteLine(string.Format(“[{0}]设置上下文…”,i));
SetCallContext(i);
WriteLine(string.Format(“[{0}]Waiting…”,i));
睡眠(5000);
WriteLine(string.Format(“[{0}]上下文为{1}”,i,GetCallContext());
});
}
私有静态void SetCallContext(int i)
{
CallContext.LogicalSetData(“测试”,i);
}
私有静态int GetCallContext()
{
return(int)CallContext.LogicalGetData(“Test”);
}
}
读取HttpContext.Current.Session
显然是安全的,因为HttpContext.Current
为每个请求返回不同的HttpContext
实例。但是由于您的Func
字段是静态的,因此替换Func
当然会导致代码错误,因为每个应用程序域只有一个静态字段实例。所以你应该采取不同的方法
例如,与其替换Func,不如只初始化它一次,并让它处理Web API情况。例如:
GetUserId = () =>
{
var context = HttpContext.Current;
// MVC / Web Forms
if (context.Session != null && context.Session["UserId"] != null) {
return (int)context.Session["UserId"];
}
// Web API
return (int)CallContext.LogicalGetData("__userId");
};
public static void RegisterWebApiUserId(int userId) {
CallContext.LogicalSetData("__userId", userId);
}
我认为您应该完全回避这个问题,并向DAL构造函数或方法调用传递一个值。我明白你想要实现什么,我只是觉得不值得。顺便说一句:HttpContext。Current是由
全局.asax
会话按请求填充的。因此每个用户会话在CallContext中都有自己的GUID键,这会导致用户id。但是DAL对象如何获得该GUID?我以前没有用过CallContext,所以请原谅我的慢。或者,DAL的每个实例化都会为该实例生成一个键,然后生成静态方法。。坚持静态方法将无法看到非静态密钥,对吗?@MattWinward:不,您在应用程序域中生成一次密钥。我更新了我的问题,让这更明显。啊,好的。因此,密钥可以是一个静态值(示例中为“_userId”),CallContext为每个“调用”存储一个值,有效地提供与会话相同的功能,但对于Web API调用?@MattWinward:“调用”将具有单个Web API请求的生存期,使用异步方法调用流,甚至,与请求中跨越的并行任务一起流动。谢谢。这太棒了。我要试一试,看看会发生什么!