Mic*_*son 8 vb.net asp.net webforms response.redirect user-experience
我正在使用新的路由功能编写asp.net 4.5应用程序.我有一个页面显示有关项目的一些信息.在Page_Load
事件中,我检查路由数据(项目ID)和用户权限,如果事情是不正确(如ID是删除项),我用Response.RedirectToRoute
送他们包装,马上回主页.不要通过GO,不要收200美元.
这是完全合理的,直到我尝试访问已删除的项目,而不是主页,我得到一个错误页面.我做了一些挖掘,发现即使在我使用之后RedirectToRoute
(与标准Redirect
方法不同),页面代码的其余部分仍继续执行,这至少看起来很浪费(因为我只是要扔掉结果)并抛出错误当必要的数据不存在时.
我做了一些更使挖掘和发现令人难以置信的邪恶是Response.End()
.它做了我需要的,但即使MSDN 页面告诉我,这Response.End
是一个古老的诅咒语言的私生子,不适合看到光明的一天.主要的反对意见似乎是Response.End抛出一个异常,这对性能有害.我不是最有经验的开发人员,所以我完全不了解这个问题,但我很难相信抛出异常比加载整个网页更加昂贵.对于如此简单的任务,变通办法似乎相当复杂和过度,特别是因为大多数页面需要某种有效性检查.
在这种情况下我该怎么办?使用Response.End
并请求原谅我的傲慢?凑齐一些丑陋的解决方法?或者我对这个问题的看法是错误的开始?我真的很想知道.
更新:现在我已经考虑了一点,我想知道我是否对这个问题有错误的观点.也许立即重定向不是对用户体验的最佳响应.我最好不要在面板中包装所有控件,并使用这样的东西?
Private Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init
'Validation Code
If notValid Then
ControlsPanel.Visible = false
ErrorPanel.Visible = true
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
Vin*_*ayC 10
RedirectToRoute实际上是包装Response.Redirect传递false
以结束请求 - 因此,请求继续.您可以使用HttpApplication.CompleteRequest作为立即调用来终止请求,以便不会调用下一个应用程序事件.
Response.End
(以及其他重定向变体)抛出ThreadAbortException
中止请求处理线程,这实际上是一种停止请求处理的坏方法.在.NET世界中,异常处理总是被认为是昂贵的,因为CLR然后需要一直向上搜索堆栈以寻找异常处理块,创建堆栈跟踪等.CompleteRequest
在.NET 1.1中引入IMO 以避免实际依赖于它的相同在ASP.NET基础结构代码中设置标志以跳过除EndRequest
事件之外的进一步处
另一种(更好的)方法是使用Server.Transfer并避免客户端往返以将重定向设置在一起.唯一的问题是客户端不会在浏览器地址栏中看到重定向的URL.我通常更喜欢这种方法.
编辑
CompleteRequest
将永远不会在页面情况下工作,其中后续页面事件仍将被调用,因为页面是处理程序,其所有事件都发生在单个(和当前)应用程序事件中ProcessRequest
.所以唯一的办法似乎是设置一个标志,检查标志覆盖,例如Render
,PreRender
,RaisePostBackEvent
等
从维护的角度来看,在基页类中具有这样的功能是有意义的(即维护标志,提供CompleteRequest
子类的方法和覆盖生命周期事件方法).例如,
internal class PageBase: System.Web.UI.Page
{
bool _requestCompleted;
protected void CompleteRequest()
{
Context.ApplicationInstance.CompleteRequest();
_requestCompleted = true;
}
protected override void RaisePostBackEvent(IPostBackEventHandler sourceControl,
string eventArgument)
{
if (_requestCompleted) return;
base.RaisePostBackEvent(sourceControl, eventArgument);
}
protected internal override void Render(HtmlTextWriter writer)
{
if (_requestCompleted) return;
base.Render(writer);
}
protected internal override void OnPreRender(EventArgs e)
{
if (_requestCompleted) return;
base.OnPreRender(e);
}
... and so on
}
Run Code Online (Sandbox Code Playgroud)
我可能会因为不直接回答问题而陷入困境,但我喜欢看到您有关用户体验的更新。我更喜欢你建议的方法。
我喜欢对无效的 id 给出 410 错误,并使用以下命令对其进行扩展(从 C# 翻译):
Protected Sub ItemDoesNotExist()
'item does not exist, serve up error page
ControlsPanel.Visible = False
ErrorPanel.Visible = True
'add meta tags for noindex
Dim mymeta As New HtmlMeta()
mymeta.Name = "robots"
mymeta.Content = "noindex"
Page.Header.Controls.Add(mymeta)
'RESPOND WITH A 410
Response.StatusCode = 410
Response.Status = "410 Gone"
Response.StatusDescription = "Gone"
Response.TrySkipIisCustomErrors = True
'important for IIS7, otherwise the Custom error page for 404 shows.
Page.Title = "item gone"
End Sub
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4642 次 |
最近记录: |