2010-12-20 72 views
9

我已經實現了一個控制器來創建新用戶。當它成功創建用戶時,它將重定向到Index()成功重定向並在失敗時顯示錯誤

我要的是重定向時一切正常,但停留在當前頁,看到了錯誤的東西時失敗。我使用jQuery ajaxMVC

我的控制器看起來是這樣的:

[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; 
}); 

當錯誤發生時它工作正常,但我不知道如何實施成功案例。

我向其他選擇開放。

+0

我有類似的情況。我有包含填寫表單的頁面。頁面上的按鈕從一個字段中提取數據,調用Web服務查找相關數據,如果查找成功,則重定向到另一個頁面。我使用Ajax來繞過數據驗證,因爲驗證字段不適用於按鈕的查找操作。如果查找失敗,我想在同一頁面上顯示一個錯誤。至少這是我想要做的。 – Suncat2000 2011-09-09 16:46:00

回答

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; 
}, 
+0

@Darin:我不確定我是否理解這個解決方案,請你能解釋它是如何工作的嗎?謝謝! – 2010-12-20 19:23:13

+1

@Daniel,在控制器動作中,我們檢查這個請求是否是一個AJAX請求('Request.IsAjaxRequest'),如果是,我們返回一個如下所示的JSON對象:'{redirectToUrl ='/ home/index'}'。 jQuery理解JSON,當它看到它時,會自動解析它,並將它傳遞給傳遞給'success'回調函數的'data'參數。所以現在在成功回調中,您可以訪問'data.redirectToUrl',它等於'/ home/index',我們使用'window.location.href'函數將瀏覽器重定向到這個url。但正如我在我的帖子中解釋的那樣,這完全沒用。 – 2010-12-20 19:25:58

+0

@Darin:如果失敗了,我需要留在頁面中。這就是我使用AJAX的原因。有沒有其他更好的方法來做到這一點? – 2010-12-20 19:28:47

0
window.location.href="url here" 

Moz Doc

+1

@Daniel:你想要去的網址 - 看起來@Darin似乎可以通過Url.Action(「Index」)解決這個問題 - 你想在哪裏取得成功? – Hogan 2010-12-20 19:28:09

1

這裏是一個採用純MVC類的備選答案,你不必硬編碼任何腳本或使用jQuery 。首先,我發現MVC 2的驗證工作正常,只要你還記得失敗和確認情況:

1)包含必要的MVC腳本(總共三個加EnableClientSideValidation調用 - 請參閱MSDN)。

2)將MetadataClassAttribute和RequiredAttribtues放置在模型/數據實體上。您不必創建單獨的元數據類,並使模型部分(我發現褲子)只引用屬性中的相同模型類。

3)解決AJAX通過返回JavaScript重定向問題,因爲已經建議(但在一個jQuery導向的方式)......

我只是驗證過程中遭受的奇怪行爲時,它已經無法從列表頁面重定向詳細信息/編輯頁面。錯誤信息會出現幾秒鐘然後消失!當然它很混亂,因爲頁面的外殼是第一個列表頁面和編輯頁面的內部內容。所以問題的根源在於現成的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進行驗證。如果他們修好了,我會很快發現。

1

如果您要在成功操作中重定向,爲什麼要使用AJAX? AJAX的目的是隻刷新站點的一部分而不重新加載整個頁面。如果任何錯誤或會話過期你要重定向,你必須重寫AuthorizeAttribute過濾器,從而使類貝爾柳默認登錄page.For:

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類你剛纔把每當調用AJAX授權象下面這樣:

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

現在你必須處理Ajax狀態302視點側上的每個Ajax調用 所以放線的佈局頁面順序碼由leadid遞減任何特定頁面,以便象下面這樣:

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

給您重定向如果當前會話過期或超時到登錄頁面。