简体   繁体   English

确定是否执行了 Server.Transfer[Request]

[英]Determine if Server.Transfer[Request] was executed

I was debugging two things and discovered that when an action executed:我正在调试两件事,发现当一个动作执行时:

Server.TransferRequest(url);
return new EmptyResult();

that my Application_Error would fire and catch the exception "The SessionStateTempDataProvider class requires session state to be enabled."我的Application_Error会触发并捕获异常“SessionStateTempDataProvider 类需要启用会话状态”。

(I do have session state enabled, specifically StateServer, and for the sake of discussion let's imagine I do not need to commit changes from this request back to the session) (我确实启用了会话状态,特别是 StateServer,为了讨论起见,让我们假设我不需要将此请求的更改提交回会话)

I'd like to control how this scenario gets logged.我想控制如何记录这种情况。 Obviously I can detect the exception type and message text, but if I wanted to not do special logging when the Request was .TransferRequest 'd (or .Transfer 'd), how can I do this?很显然,我可以检测异常类型和消息文本,但如果我想没有做特别记录时,请求被.TransferRequest “d(或.Transfer ” d),我该怎么办呢?

I have already examined Response.IsRequestBeingRedirected - it was false .我已经检查过Response.IsRequestBeingRedirected - 它是false

Each Server.Transfer will add an unsafe request completion call to the stack, therefore, if there are more than 1 of this, you may think that the request is internally redirected by one of the Server.Transfer or Server.TransferRequest methods每个 Server.Transfer 都会向堆栈中添加一个不安全的请求完成调用,因此,如果其中超过 1 个,您可能会认为该请求是由Server.TransferServer.TransferRequest方法之一在内部重定向的

Here is a boolean function which you can add to your global.asax file, which will return true if it finds more than one instances of request completion frames in the current stack trace.这是一个布尔函数,您可以将其添加到 global.asax 文件中,如果在当前堆栈跟踪中找到多个请求完成帧实例,它将返回 true。

The new StackTrace() is an expensive operation, but, because this is executing in an Exceptional context here, it's overhead "may" be ignored. new StackTrace()是一个开销很大的操作,但是,因为这里是在 Exceptional 上下文中执行的,所以它的开销“可能”被忽略。

private bool IsRequestTransferred()
{
    System.Diagnostics.StackTrace stackTrace = new System.Diagnostics.StackTrace();
    int requestCompletionCount = 0;
    foreach (var stackFrame in stackTrace.GetFrames())
    {
        System.Reflection.MethodBase methodBase = stackFrame.GetMethod();
        if (methodBase.DeclaringType.Name == "UnsafeIISMethods" && methodBase.Name == "MgdIndicateCompletion")
        {
            if (++requestCompletionCount == 2)
            {
                return true;
            }
        }
    }
    return false;
}

void Application_Error(object sender, EventArgs e)
{
    bool isRequestTransferred = IsRequestTransferred();
}

Server.TransferRequest accepts headers collection. Server.TransferRequest接受标头集合。 You can add a special technical header and then look for it later.您可以添加一个特殊的技术标题,然后稍后再查找。

Server.TransferRequest(url,
    true,
    method: "GET",
    headers: new NameValueCollection() { { "transferred", "true" } });

//and then
bool isTransferred = (Request.Headers["transferred"] != null);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM