如何从 ASP.NET 委托中执行 Response.Redirect
How to do a Response.Redirect from a ASP.NET delegate
我尝试了以下典型方法,但无法从异步 ASP.NET 方法进行重定向:
Response.Redirect("~/Login.aspx");
HttpContext.Current.Response.Redirect("~/Login.aspx");
我也尝试过 Server.Transfer
但由于引用方法(委托)中的页面控件不可用而无法成功。
我已经尝试了一个静态 属性,我在其中填写了委托响应并在客户端使用 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);
}
}
当没有可用的控件且不使用任何静态 属性 时,从委托函数执行重定向的替代方法或最佳方法是什么?
Response.Redirect
方法使用ThreadAbortException
停止当前请求的执行。
当您捕获该异常并吸收它时,请求处理将照常进行并忽略您尝试执行的重定向。
您可以使用变量来标记您希望进行重定向,然后在 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");
}
}
您无法从 ASP.Net 中的异步操作发出 HTTP 重定向调用,但有可行的替代方法。我将使我的回答通用化,希望能帮助其他读者,但作为 SignalR 用户,您需要查看数字 3。
让我们检查 3 个场景:
异步操作是从使用 HostingEnvironment.QueueBackgroundWorkItem (.NET 4.5.2 onwards).
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 的正常 HTTP 请求中开始的,使用到期时间将用户重定向到 next 请求。
您的客户端通过网络套接字连接,您的服务器端实现使用 Microsoft.WebSockets.dll。与网络服务器的连接升级为全双工套接字连接;它不是页面的 url 而是通信连接,因此没有任何重定向。
相反,您通过连接发送命令通知客户端代码重定向需要并且您在 JavaScript 中执行重定向。在WebSocketHandler
中,用这个例子发送一个字符串命令:
Send("LOGOFF");
并在 JavaScript ws.onmessage
处理程序中,将消息标识为 "LOGOFF" 并将 window.location.href 更改为目标页面:
ws.onmessage = function (message) {
switch (message.data) {
case "LOGOFF":
location.href = "Login.aspx";
}
};
上面的例子被简化了。我有一个执行此操作的站点,实际上发送了一个 class(JSON 序列化),其中包含命令类型和可选有效负载。
SignalR has the same issues as #2 and I would propose a similar solution. I've not worked with SignalR yet but according to a comment on this answer 你会像这样发送命令:
GlobalHost.ConnectionManager.GetHubContext<Chat>().Clients.Client(connectionId).addMessage("LOGOFF");
在您的 SignalR 客户端消息处理程序中查找 LOGOFF 消息,并将 window 位置 href 设置为您的登录页面。
这是我多年前所做的。我将它张贴在这里是为了帮助其他问我的人。
嗯,这显然不能通过异步 ASP.NET 方法(委托)完成。
因此,为了实现所需的功能,我通过在 SignalR 中使用普通广播的方法向客户端传递了一个值。
在客户端,我正在相应地验证和执行操作。我已经使用简单的 JavaScript 更改了 URL。我正在使用最简单的代码来理解使用 SignalR 从 ASP.NET 重定向的核心概念。
代码隐藏
[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...
}
};
我尝试了以下典型方法,但无法从异步 ASP.NET 方法进行重定向:
Response.Redirect("~/Login.aspx");
HttpContext.Current.Response.Redirect("~/Login.aspx");
我也尝试过 Server.Transfer
但由于引用方法(委托)中的页面控件不可用而无法成功。
我已经尝试了一个静态 属性,我在其中填写了委托响应并在客户端使用 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);
}
}
当没有可用的控件且不使用任何静态 属性 时,从委托函数执行重定向的替代方法或最佳方法是什么?
Response.Redirect
方法使用ThreadAbortException
停止当前请求的执行。
当您捕获该异常并吸收它时,请求处理将照常进行并忽略您尝试执行的重定向。
您可以使用变量来标记您希望进行重定向,然后在 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");
}
}
您无法从 ASP.Net 中的异步操作发出 HTTP 重定向调用,但有可行的替代方法。我将使我的回答通用化,希望能帮助其他读者,但作为 SignalR 用户,您需要查看数字 3。
让我们检查 3 个场景:
异步操作是从使用 HostingEnvironment.QueueBackgroundWorkItem (.NET 4.5.2 onwards).
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 的正常 HTTP 请求中开始的,使用到期时间将用户重定向到 next 请求。您的客户端通过网络套接字连接,您的服务器端实现使用 Microsoft.WebSockets.dll。与网络服务器的连接升级为全双工套接字连接;它不是页面的 url 而是通信连接,因此没有任何重定向。
相反,您通过连接发送命令通知客户端代码重定向需要并且您在 JavaScript 中执行重定向。在
WebSocketHandler
中,用这个例子发送一个字符串命令:Send("LOGOFF");
并在 JavaScript ws.onmessage
处理程序中,将消息标识为 "LOGOFF" 并将 window.location.href 更改为目标页面:
ws.onmessage = function (message) {
switch (message.data) {
case "LOGOFF":
location.href = "Login.aspx";
}
};
上面的例子被简化了。我有一个执行此操作的站点,实际上发送了一个 class(JSON 序列化),其中包含命令类型和可选有效负载。
SignalR has the same issues as #2 and I would propose a similar solution. I've not worked with SignalR yet but according to a comment on this answer 你会像这样发送命令:
GlobalHost.ConnectionManager.GetHubContext<Chat>().Clients.Client(connectionId).addMessage("LOGOFF");
在您的 SignalR 客户端消息处理程序中查找 LOGOFF 消息,并将 window 位置 href 设置为您的登录页面。
这是我多年前所做的。我将它张贴在这里是为了帮助其他问我的人。
嗯,这显然不能通过异步 ASP.NET 方法(委托)完成。
因此,为了实现所需的功能,我通过在 SignalR 中使用普通广播的方法向客户端传递了一个值。
在客户端,我正在相应地验证和执行操作。我已经使用简单的 JavaScript 更改了 URL。我正在使用最简单的代码来理解使用 SignalR 从 ASP.NET 重定向的核心概念。
代码隐藏
[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...
}
};