我已经实现了一个控制器来创建新用户。成功创建用户后,它会重定向到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;
});
发生错误时工作正常,但我不知道如何实现成功案例。
我对其他选择开放了。
答案 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"