简体   繁体   English

如何从ASP.NET委托执行Response.Redirect

[英]How to do a Response.Redirect from a ASP.NET delegate

I have tried the following typical approaches but couldn't able to do a redirect from an asynchronous ASP.NET method: 我尝试了以下典型方法,但无法从异步ASP.NET方法进行重定向:

Response.Redirect("~/Login.aspx");

HttpContext.Current.Response.Redirect("~/Login.aspx");

I have also tried Server.Transfer but couldn't get success due to the unavailability of the page controls inside a reference method(delegate). 我也尝试了Server.Transfer但是由于引用方法(委托)中页面控件的不可用而无法获得成功。

I have already tried a static property which I filled in delegate response and continuously checking it on client side using ASP.NET SignalR to perform a redirect but as it a static property, it redirects all the user to the login page which I don't want to do it. 我已经尝试了一个静态属性,该属性我填写了委托响应,并使用ASP.NET SignalR在客户端不断对其进行检查以执行重定向,但是由于它是一个静态属性,它将所有用户重定向到我不登录的页面想做。

private void Response_Recieved(Message objMessage)
{
    try
    {
        if (objMessage.OperationType == Operation.Data)
        {
            NotificationMessage  objNotifications = new DataProcess().Deserialize_Messages(objMessage);
            _jsonData = JsonConvert.SerializeObject(objNotifications);
        }
        else if (objMessage.OperationType == Operation.ServerAbnormalDisconnect)
        {
            // I want to redirect a user to login page whenever server disconnects
            HttpContext.Current.Response.Redirect("~/Login.aspx");
            //Response.Redirect("~/Login.aspx");
        }

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}

What would be the alternative or best approach to perform a redirect from a delegate function when there is no control available also without using any static property? 如果没有控件也没有使用任何静态属性,那么从委托函数执行重定向的另一种或最佳方法是什么?

You can't issue a HTTP redirect call from an asynchronous operation in ASP.Net but there are viable alternatives. 您不能从ASP.Net中的异步操作发出HTTP重定向调用,但是有可行的选择。 I will make my answer generic to hopefully help other readers but as a SignalR user you need to look at number 3. 我将通用答案,以期希望对其他读者有所帮助,但是作为SignalR用户,您需要看一下数字3。

Let's examine 3 scenarios: 让我们检查3种情况:

  1. An async operation is commenced from within a normal HTTP request using HostingEnvironment.QueueBackgroundWorkItem (.NET 4.5.2 onwards). 使用HostingEnvironment.QueueBackgroundWorkItem (.NET 4.5.2及更高版本)从常规HTTP请求中开始异步操作。

    The resource requested is (where applicable) processed/rendered, and returned. (在适用的情况下)处理/渲染请求的资源,然后将其返回。 The request is completed. 请求已完成。 There is no longer any request to redirect. 不再有任何重定向请求。 In this scenario, you could perhaps store a value in the Application cache with an expiry time to redirect the user on the next request. 在这种情况下,您可能会在到期时将一个值存储在应用程序缓存中 ,以便在下一个请求时重定向用户。

  2. Your clients are connected by way of web socket and your server side implementation uses Microsoft.WebSockets.dll . 您的客户端通过Web套接字连接,服务器端实现使用Microsoft.WebSockets.dll The connection to the web server is upgraded to a full-duplex socket connection; 与Web服务器的连接已升级为全双工套接字连接; it is not the url for the page but a comms connection so there is nothing to redirect. 它不是页面的url,而是comms连接,因此没有要重定向的内容。

    Instead, you send a command over the connection informing the client side code that a redirect is needed and you perform the redirect in JavaScript. 而是通过连接发送命令,通知客户端代码需要重定向,然后使用JavaScript执行重定向。 In the WebSocketHandler , with this example sending a string command: WebSocketHandler ,通过以下示例发送字符串命令:

    Send("LOGOFF");

and in the JavaScript ws.onmessage handler, identify the message as "LOGOFF" and change the window.location.href to the target page: 在JavaScript ws.onmessage处理程序中,将消息标识为“ LOGOFF”,然后将window.location.href更改为目标页面:

    ws.onmessage = function (message) {
        switch (message.data) {
            case "LOGOFF":
                location.href = "Login.aspx";
        }
    };

The above example is simplified. 上面的示例已简化。 I have a site which does this and actually send a class (JSON serialised) with a command type and optional payload. 我有一个这样做的站点,实际上发送一个带有命令类型和可选有效负载的类(JSON序列化)。

  1. SignalR has the same issues as #2 and I would propose a similar solution. SignalR与#2存在相同的问题,我将提出类似的解决方案。 I've not worked with SignalR yet but according to a comment on this answer you would send the command like so: 我尚未使用SignalR,但根据对此答案的评论,您将像这样发送命令:

    GlobalHost.ConnectionManager.GetHubContext<Chat>().Clients.Client(connectionId)‌​.addMessage("LOGOFF");

Look out for the LOGOFF message in your SignalR client-side message handler and set the window location href to your login page. 在SignalR客户端消息处理程序中查找LOGOFF消息,并将窗口位置href设置为登录页面。

The Response.Redirect method uses a ThreadAbortException to stop the execution of the current request. Response.Redirect方法使用ThreadAbortException停止当前请求的执行。

As you are catching that exception and just absorbing it, the request handling will just go on as usual and ignore the redirect that you tried to do. 当您捕获该异常并吸收它时,请求处理将照常进行,并忽略您尝试执行的重定向。

You can use a variable to flag your desire to do the redirect, and then perform it outside the try...catch : 您可以使用变量来标记您想要进行重定向的愿望,然后在try...catch之外执行它:

private void Response_Recieved(Message objMessage) {
  bool doRedirect = false;
  try {
    if (objMessage.OperationType == Operation.Message_Response) {
      NotificationMessage  objNotifications = new DataProcess().Deserialize_Messages(objMessage);
      _jsonData = JsonConvert.SerializeObject(objNotifications);
    } else if (objMessageBo.OperationType == Operation.ServerAbnormalDisconnect) {
      // I want to redirect a user to login page whenever server disconnects
      doRedirect = true;
    }
  } catch (Exception ex) {
    Logger.WriteException(ex);
  }
  if (doRedirect) {
    HttpContext.Current.Response.Redirect("~/Login.aspx");
  }
}

Here is what I had done years back. 这是几年前我所做的。 I am posting it here to help others who are asking me. 我将其张贴在这里以帮助其他询问我的人。

Well it is clearly can't be done from an asynchronous ASP.NET method(delegate). 好吧,这显然是无法通过异步ASP.NET方法(委托)完成的。

So to achieve the desire functionality I passed a value to the client side from the method using normal broadcasting in SignalR. 因此,为了实现所需的功能,我使用SignalR中的常规广播从该方法向客户端传递了一个值。

And on client side, I am validating and performing actions accordingly. 在客户端,我正在验证并相应地执行操作。 I have changed the URL using simple JavaScript. 我已经使用简单的JavaScript更改了网址。 I am putting a simplest code to understand the core concept of redirection from ASP.NET using SignalR. 我使用最简单的代码来理解使用SignalR从ASP.NET重定向的核心概念。

Code Behind 背后的代码

[HubMethodName("getSessionState")] 
public string GetSessionState(string status) {

    return Clients.Caller.UpdatedState(status);

}

private void Response_Recieved(Message objMessage)
{
    try
    {
        if (objMessage.OperationType == Operation.Data)
        {
            NotificationMessage  objNotifications = new DataProcess().Deserialize_Messages(objMessage);
            _jsonData = JsonConvert.SerializeObject(objNotifications);

            SendNotifications(_jsonData);
        }
        else if (objMessage.OperationType == Operation.ServerAbnormalDisconnect)
        {
            GetSessionState("false");   //<--- Disconnecting session by passing false for sessionstate
        }

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
} 


var notifications = $.connection.notificationsHub;

notifications.client.updatedState = function (status) {

    if (status === "false") {

        window.alert("Server is disconnected. Forced logout!");

        window.location.href = "/logout.aspx"
    }
    else {

        // Doing my stuff here...

    }

};

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

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