在Asp.NETMVC5中处理会话和多个辅助进程

在Asp.NETMVC5中处理会话和多个辅助进程,asp.net,asp.net-mvc,session,worker-process,Asp.net,Asp.net Mvc,Session,Worker Process,我有一个Asp.NETMVC5Web应用程序,它有一个在DB中记录错误的错误处理机制,并以一种称为ErrorPage的单独形式向提出错误的用户显示errorId。当web应用程序中发生错误时,我将该errorId存储在会话中,并从ErrorPage中的会话中读取该错误ID,以便向遇到此错误的用户显示该errorId,以便能够进行备份操作。此web应用程序的web服务器当前仅使用一个工作进程处理请求,因此所有生成的会话在整个web应用程序中都有效且可访问。 我打算将此web应用的工作进程数从1增加

我有一个Asp.NETMVC5Web应用程序,它有一个在DB中记录错误的错误处理机制,并以一种称为ErrorPage的单独形式向提出错误的用户显示errorId。当web应用程序中发生错误时,我将该errorId存储在会话中,并从ErrorPage中的会话中读取该错误ID,以便向遇到此错误的用户显示该errorId,以便能够进行备份操作。此web应用程序的web服务器当前仅使用一个工作进程处理请求,因此所有生成的会话在整个web应用程序中都有效且可访问。

我打算将此web应用的工作进程数从1增加到4,但我的web应用有一些问题。同样在IIS中,我将会话状态模式设置为进程中模式,因为在很多情况下我在web应用中使用了会话,而我无法将其设置为SQL Server模式,因为这会增加性能开销。

问题是,当一个请求进入工作进程a(例如)时,将在工作进程a中为该请求生成一个会话,并且假设该请求在web应用程序中遇到错误,我会将用户重定向到ErrorPage,并且有可能是该新请求(将用户重定向到ErrorController中的ErrorPage操作)进入另一个辅助进程B(例如)。但是在辅助进程B中,我无法访问为第一个请求生成的会话,因为该会话是在辅助进程级别定义的,并且它们仅在该辅助进程中有效

所以在对这个进行了大量搜索之后,我决定将会话信息保存在DB中而不是Ram中,并在需要时从DB中加载它。但我不知道用哪个密钥ID在DB中保存此信息

想象一下这个场景,更容易发现我真正的问题:

让我们来看看:

WorkerProcessId1 = W1;
WorkerProcessId2 = W2;
SessionId1 = S1;
SessionId2 = S2;
RequestId1 = R1;
RequestId2 = R2;
R1 comes to web server
==> web server passes R1 to W1
==> W1 generates S1 for R1
==> R1 faces an error
==> for the user who sends R1 (it is possible the user has not logged in yet so I don't know the userId), I will save the error in DB using the combination of S1 and userId in a specific pattern as a unique identifier in Error table in DB
==> the user will redirect to ErrorPage with another request R2
==> web server passes R2 to W2
==> W2 generates S2 for R2
==> after the redirect is done, in the ErrorPage I need the errorId of that error which I save it to DB, for showing it to the user for backup operations
==> I don't know which error belongs to this user and which error should be load from DB????
和场景:

WorkerProcessId1 = W1;
WorkerProcessId2 = W2;
SessionId1 = S1;
SessionId2 = S2;
RequestId1 = R1;
RequestId2 = R2;
R1 comes to web server
==> web server passes R1 to W1
==> W1 generates S1 for R1
==> R1 faces an error
==> for the user who sends R1 (it is possible the user has not logged in yet so I don't know the userId), I will save the error in DB using the combination of S1 and userId in a specific pattern as a unique identifier in Error table in DB
==> the user will redirect to ErrorPage with another request R2
==> web server passes R2 to W2
==> W2 generates S2 for R2
==> after the redirect is done, in the ErrorPage I need the errorId of that error which I save it to DB, for showing it to the user for backup operations
==> I don't know which error belongs to this user and which error should be load from DB????
如果无法做到这一点,是否有任何方法可以在web服务器的所有工作进程中共享标识符?

编辑:

WorkerProcessId1 = W1;
WorkerProcessId2 = W2;
SessionId1 = S1;
SessionId2 = S2;
RequestId1 = R1;
RequestId2 = R2;
R1 comes to web server
==> web server passes R1 to W1
==> W1 generates S1 for R1
==> R1 faces an error
==> for the user who sends R1 (it is possible the user has not logged in yet so I don't know the userId), I will save the error in DB using the combination of S1 and userId in a specific pattern as a unique identifier in Error table in DB
==> the user will redirect to ErrorPage with another request R2
==> web server passes R2 to W2
==> W2 generates S2 for R2
==> after the redirect is done, in the ErrorPage I need the errorId of that error which I save it to DB, for showing it to the user for backup operations
==> I don't know which error belongs to this user and which error should be load from DB????
在本次编辑中,我将解释我在错误处理机制中使用会话的位置和方式。在目标行的末尾有一个注释短语,上面写着“我正在使用会话”:

名称空间MyDomain.UI.Infrastructure.Attributes
{
公共类CustomHandleErrorAttribute:HandleErrorAttribute
{
公共CustomHandleErrorAttribute()
{
}
公共覆盖无效OneException(例外上下文筛选器上下文)
{
if(filterContext.ExceptionHandled | | |!filterContext.HttpContext.IsCustomErrorEnabled)
{
返回;
}
如果(!ExceptionType.IsInstanceOfType(filterContext.Exception))
{
返回;
}
var errorid=0;
尝试
{
errorid=SaveErrorToDatabase(filterContext);
}
捕获(例外e)
{
//控制台写入线(e);
//投掷;
}
//如果请求是AJAX,则返回JSON else视图。
if(filterContext.HttpContext.Request.Headers[“X-Requested-With”]=“XMLHttpRequest”)
{
filterContext.Result=新的JsonResult
{
JsonRequestBehavior=JsonRequestBehavior.AllowGet,
数据=新
{
错误=真,
message=“错误消息…”,
errorid,
}
};
}
其他的
{
var controllerName=(字符串)filterContext.RouteData.Values[“controller”];
var actionName=(字符串)filterContext.RouteData.Values[“action”];
var model=newhandleerrorinfo(filterContext.Exception、controllerName、actionName);
filterContext.Controller.TempData.Clear();
filterContext.Controller.TempData.Add(“ErrorCode”,errorid);//我正在使用会话
filterContext.Result=新的ViewResult
{
ViewName=视图,
MasterName=Master,
ViewData=新的ViewDataDictionary(型号),
TempData=filterContext.Controller.TempData
};
}
filterContext.ExceptionHandled=true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode=500;
filterContext.HttpContext.Response.TrySkipIisCustomErrors=true;
}
私有int-SaveErrorToDatabase(异常上下文异常)
{
MyDomainDBContext=新的MyDomainDBContext();
var browserType=exception.HttpContext.Request.Browser.Capabilities[“type”];
var错误=新错误
{
ErrorURL=exception.HttpContext.Request.Url.ToString()异常,
ExceptionType=exception.exception.GetType().Name,
IsGlobalError=false,
Message=exception.exception.Message,
StackTrace=exception.exception.StackTrace,
ThrownTime=日期时间。现在,
UserIP=IPAddress.Parse(exception.HttpContext.Request.UserHostAddress.ToString(),
BrowserName=browserType.ToString()+“,”+
GetUserPlatform(exception.HttpContext.Request)
};
AddRequestDetails(exception.exception、exception.HttpContext.Request、error);
if(exception.exception.InnerException!=null)
{
错误。消息+=“\n内部异常:\n”+exception.exception.InnerException.Message;
如果(exception.exception.InnerException.InnerException=