成功重定向并在失败时显示错误

时间:2010-12-20 19:16:24

标签: jquery ajax asp.net-mvc asp.net-mvc-2

我已经实现了一个控制器来创建新用户。成功创建用户后,它会重定向到Index()

我想要的是重定向,一切正常,但留在当前页面,并在出现问题时看到错误。

我正在jQuery ajax使用MVC

我的控制器看起来像这样:

[Authorize]
public ActionResult CreateUser(string username)
{
    try
    {
        //here the logic to create the user
    }   
    catch (Exception ex)
    {
        string error = string.Format("Error creating user: {0}", ex.Message);
        Response.StatusCode = 500;
        Response.Write(error);    
    }
    return RedirectToAction("Index");
}

使用jQuery拦截表单提交,然后使用ajax:

进行调用
$("#new-user-form").submit(function() {
    var form = $(this);
    $.ajax({
    type: "GET",
        url: form.attr('action'),
        data: form.serialize(),
        success: function(data, textStatus, xhr) {
            //At this point I would like to redirect
        },
        error: function(xhr, textStatus, errorThrown) {
            $(".error-summary").html(xhr.responseText);
        }
    });

    //cancel the event
    return false;
});

发生错误时工作正常,但我不知道如何实现成功案例。

我对其他选择开放了。

4 个答案:

答案 0 :(得分:29)

如果您要在成功动作中重定向,为什么使用AJAX? AJAX的目的是仅刷新站点的一部分而不重新加载整个页面。如果在成功动作中你将重定向,那将完全击败你从AJAX获得的所有目的和好处。但是因为你问这里你能做什么:

[Authorize]
public ActionResult CreateUser(string username)
{
    ...
    if (Request.IsAjaxRequest())
    {
        return Json(new { redirectToUrl = Url.Action("Index") });
    }
    return RedirectToAction("Index");
}

然后:

success: function(data, textStatus, xhr) {
    window.location.href = data.redirectToUrl;
},

答案 1 :(得分:2)

如果您要在成功动作中重定向,为什么使用AJAX? AJAX的目的是仅刷新站点的一部分而不重新加载整个页面。如果在任何错误或会话过期,您将重定向默认登录页面。为此,您必须覆盖AuthorizeAttribute过滤器,所以make class belew:

public class CheckAuthorization : AuthorizeAttribute
{

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (HttpContext.Current.Session["AFSUserId"] == null || !HttpContext.Current.Request.IsAuthenticated)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.HttpContext.Response.StatusCode = 302; //Found Redirection to another page. Here- login page. Check Layout ajaxError() script.
                filterContext.HttpContext.Response.End();
            }
            else
            {
                filterContext.Result = new RedirectResult(System.Web.Security.FormsAuthentication.LoginUrl + "?ReturnUrl=" +
                filterContext.HttpContext.Server.UrlEncode(filterContext.HttpContext.Request.RawUrl));
         }
     }
}

完成CheckAuthorization Class之后,只要你调用ajax授权,就像下面那样:

[CheckAuthorization]
public class BuyerController : Controller
{
    [HttpGet()]
    public ActionResult GetOrderlist()
    {
        return View();
    }
}

现在你必须在每个Ajax调用的视图侧处理ajax状态302 因此,通过leadid desc将任何特定页面的代码行放入您的布局页面顺序中,如下所示:

    $(document).ajaxError(function (event, jqXHR, ajaxSettings, thrownError) {
        if (jqXHR.status == 302) {
            window.location.href = '@Url.Action("Login", "Home")';
        }
    });

如果当前会话过期或超时,您将重定向到登录页面。

答案 2 :(得分:1)

这是一个使用纯MVC类的替代答案,您不必对任何脚本进行硬编码或使用jQuery。首先,我发现MVC 2的验证器在成功,失败和确认案例中都能正常工作,只要你还记得:

1)包含必要的MVC脚本(总共三个加上EnableClientSideValidation调用 - 请参阅MSDN)。

2)将MetadataClassAttribute和RequiredAttribtues放在模型/数据实体上。您不必创建单独的元数据类,并使您的模型部分(我发现裤子)只引用属性中的相同模型类。

3)按照已经建议的方式返回JavaScript解决AJAX重定向问题(但是以面向jQuery的方式)......

我在验证过程中遇到了奇怪的行为,因为它已无法从列表页面重定向到详细信息/编辑页面。错误消息将出现几秒钟然后消失!当然它很混乱,因为页面的shell是第一个列表页面和编辑页面的内部内容。因此问题的根本原因是开箱即用的MVC 2工具包无法从第一页正确地重定向,而不是验证器在第二页上无法正常工作。

我在这里找到了相同的解决方案:

http://craftycodeblog.com/2010/05/15/asp-net-mvc-ajax-redirect/ ...我在VB.NET中扩展为扩展方法和类:

    ''' <summary>
    ''' MVC extension methods.
    ''' </summary>
    Public Module MvcExtensions

        ''' <summary>
        ''' Returns an <see cref="AjaxAwareRedirectResult"/> for the specified action
        ''' and optional controller name.
        ''' </summary>
        <Extension()> _
        Public Function AjaxAwareRedirectToAction(controller As Controller, _
                                         actionName As String, _
                                         Optional controllerName As String = Nothing) _
                                     As RedirectResult

            ' Get target URL
            Dim url = controller.Url.Action(actionName, controllerName)

            ' Return AJAX aware redirect result
            Return New AjaxAwareRedirectResult(url)

        End Function

   End Module

    ''' <summary>
    ''' <see cref="RedirectResult"/> which works with MVC 2 AJAX.
    ''' </summary>
    ''' <remarks>
    ''' Normal redirects do not work with AJAX partial updates in MVC (HTTP 302 status).
    ''' With MVC 2 AJAX it is necessary to return JavaScript to change the browser location.
    ''' </remarks>
    Public Class AjaxAwareRedirectResult
        Inherits RedirectResult

        ''' <summary>
        ''' Creates an instance which redirects to the specified URL using
        ''' a response containing either AJAX JavaScript or classic HTTPS 302 status.
        ''' </summary>
        ''' <param name="url">Target URL.</param>
        Sub New(url As String)
            MyBase.New(url)
        End Sub

        ''' <summary>
        ''' Generates the response.
        ''' </summary>
        Public Overrides Sub ExecuteResult(ByVal context As ControllerContext)

            ' Check if AJAX was used for request
            If context.RequestContext.HttpContext.Request.IsAjaxRequest Then

                ' Perform JavaScript redirect when AJAX is used
                Dim destinationUrl As String = UrlHelper.GenerateContentUrl(Url, context.HttpContext)
                Dim result As JavaScriptResult = New JavaScriptResult With {
                        .Script = ("window.location='" + destinationUrl + "';")}
                result.ExecuteResult(context)

            Else

                ' Perform classic HTTP 302 status redirect
                MyBase.ExecuteResult(context)

            End If

        End Sub

    End Class

那么你有两个选择。您可以遵循为MVC目标调用AjaxAwareRedirectToAction(aciton,[controller])的典型MVC模式,或者在您考虑到特定URL目标(即外部站点)时返回AjaxAwareRedirectResult(url)的新实例。

我真的很惊讶微软没有在第一个MVC 2 RTM中对AJAX重定向进行排序。我必须在我当前的项目中使用MVC 2,这就是为什么我必须忍受这个限制,但也有一些新的MVC解决方案,我看到更倾向于jQuery进行验证。如果他们修好了我会很快发现的。

答案 3 :(得分:0)

 window.location.href="url here"

Moz Doc