在ajax请求期间ASP.NET授权失败时正确处理案例

时间:2013-10-28 14:40:55

标签: ajax asp.net-mvc asp.net-mvc-3

我正在开发一个asp.net MVC3应用程序。

我有LiveFeedController方法,根据用户选择的选项返回项目列表。它返回完整视图或部分视图,具体取决于请求是否为ajax请求。

例如:

  Public Class LiveFeedController
  Inherits System.Web.Mvc.Controller

        <Authorize(Roles:="CanViewFeed")>
        Function Feed(Optional ByVal feedID As Nullable(Of Guid) = Nothing, Optional ByVal itemID As Nullable(Of Guid) = Nothing, Optional ByVal refreshTimer As Double = 0.0) As ActionResult
            Dim feedVM As New FeedViewModel
            feedVM.SelectedFeedID = feedID 
            feedVM.SelectedItemID = itemID 
            feedVM.RefreshTimer = refreshTimer
            Return View(feedVM)
        End Function

        <Authorize(Roles:="CanViewFeed")>
        <HttpPost()>
        Function Feed(ByVal collection As FormCollection) As ActionResult
            Dim feedVM As New FeedViewModel
            TryUpdateModel(feedVM , collection)
            If Request.IsAjaxRequest Then
                Return PartialView("PartialFeed", feedVM)
            End If
            Return View(feedVM)
        End Function

我的问题是,如果将ajax请求提交给HttpPost方法,并且用户不再登录(因此Authorize失败),则返回的内容是我在web.config文件中指定的登录页面:

<authentication mode="Forms">
  <forms loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>

这显示在我的页面/视图的动态部分中,但它使html无效,因为返回的内容是登录页面的完整视图。

我也想避免这个问题,并正确显示登录页面的内容。我怎么能做到这一点?

谢谢,

-Frinny

1 个答案:

答案 0 :(得分:1)

我通过阅读这个帖子找到了解决问题的方法:How to manage a redirect request after a jQuery Ajax call。我使用的解决方案没有标记为主题的答案。

这就是我所做的。

在我的Global.asax.vb文件中,我实现了一个处理PreSendRequestHeaders事件的方法。如果Response.StatusCode指示重定向(302),并且如果请求是Ajax请求,则将状态代码更改为“OK”(200)并添加指示需要身份验证的标头。我还添加了一个名为New_Location的标头,指示浏览器应该重定向到的位置。

Private Sub MvcApplication_PreSendRequestHeaders(sender As Object, e As System.EventArgs) Handles Me.PreSendRequestHeaders
    If Context.Response.StatusCode = 302 And New HttpContextWrapper(Context).Request.IsAjaxRequest Then
        Context.Response.StatusCode = 200
        Context.Response.AddHeader("REQUIRES_AUTH", "1")
        Context.Response.AddHeader("NEW_LOCATION", Context.Response.RedirectLocation)
    End If
End Sub

现在,在处理我的Ajax成功事件的函数中,我检查REQUIRES_AUTH标头是否设置为'1',如果是,我将用户重定向到{{1标题。

像这样:

NEW_LOCATION

此解决方案允许我将窗口重定向到完整登录页面,以避免在我的实时Feed内容中呈现登录页面时出现问题。

-Frinny