所以我读了很多关于如何正确使用Response.Redirect而不会导致一些错误。
Response.Redirect(url, false);
Context.ApplicationInstance.CompleteRequest();
情况:用户登录站点并访问列出表单的页面。用户在该页面上坐了一个小时,什么都不做(将其记录下来)。用户单击按钮以编辑标题(需要回发)。这导致用户对象为空,因为它将其记录在会话之外。
我做了什么:在页面加载中,检查用户对象是否为空,如果是,则重定向到登录页面。应该发生什么呢?
问题:按钮事件仍然是STILL触发。是因为我有以下代码行吗?
Context.ApplicationInstance.CompleteRequest();
当我只想重定向到登录页面时,如何阻止事件被触发?
我知道我可以在重定向代码中提供true,但这会导致错误吗?
Response.Redirect(url, true);
我目前做的事情(这不是我所知道的最佳方式):在按钮事件中,我再次检查用户对象是否为空。如果它不为空,请继续编辑代码以编辑标题(记录编辑者)。这是一种处理这种情况的坏方法。
我所看到的:用Response.IsRequestBeingRedirected包装所有事件。但如果我有几个页面和很多按钮事件,这可能会有点烦人。这是处理这种情况的唯一方法吗?
示例:
protected void Page_Load(object sender, EventArgs e)
{
Account account = Session["Account"] as Account;
if (account == null)
{
Response.Redirect("WebForm1.aspx?NewSession=true", false);
Context.ApplicationInstance.CompleteRequest();
return;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Account account = Session["Account"] as Account;
Label1.Text = account.userID.ToString();
}
同样,如果我已在页面上,并且会话已过期,并且我单击Button1,则仍会调用Button1_Click方法。我提供的内容会给我一个" NullReferenceException"。正在调用Page_Load,它正在进行重定向。但是,即使在Page_Load中使用return语句,仍然会调用Button1_Click。
谢谢!
答案 0 :(得分:3)
你对Response.Redirect(url, true)
是正确的。它有点贵,因为它抛出ThreadAbortException
导致当前线程终止,这不是你想要的大多数时间。
此主题KB312629上甚至存在KB。
是的,使用您的代码,无法阻止使用内置类/方法为当前IHttpHandler
(Page
类实现)触发事件。
所以我建议创建基页类并添加一个bool
字段,指示请求完成请求加上调用ApplicationInstance.CompleteRequest
的方法,并将标志设置为true
。此外,您还需要覆盖RaisePostBackevent
方法来控制页面上的控件(非页面)事件调用。
public abstract class BasePage : Page
{
private bool shouldNotRaiseEvents;
protected void CompleteRequest()
{
shouldNotRaiseEvents = true;
Context.ApplicationInstance.CompleteRequest();
}
protected override void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
{
if (shouldNotRaiseEvents)
{
return;
}
base.RaisePostBackEvent(sourceControl, eventArgument);
}
}
您的更新代码将是:
Response.Redirect(url, false);
CompleteRequest();
另请注意,如果您在LoadComplete
,PreRender
,SaveViewState
,Render
,Unload
事件处理程序中有内容,并且您不希望这样要在重定向调用后执行的代码,您还需要覆盖这些方法。