如何得到一个ASP.NET MVC的Ajax响应redirect到新的页面,而不是将视图插入到UpdateTargetId?

我正在使用Ajax.BeginForm来创build一个表单,将执行一个AJAX回发到一个特定的控制器操作,然后如果操作成功,用户应该被redirect到另一个页面(如果操作失败,则状态消息显示使用AjaxOptions UpdateTargetId)。

using (Ajax.BeginForm("Delete", null, new { userId = Model.UserId }, new AjaxOptions { UpdateTargetId = "UserForm", LoadingElementId = "DeletingDiv" }, new { name = "DeleteForm", id = "DeleteForm" })) { [HTML DELETE BUTTON] } 

如果删除成功,我将返回一个redirect结果:

 [Authorize] public ActionResult Delete(Int32 UserId) { UserRepository.DeleteUser(UserId); return Redirect(Url.Action("Index", "Home")); } 

但主控制器索引视图正在加载到UpdateTargetId,因此我最终在一个页面内的页面。 我正在考虑两件事情:

  1. 要么我构build这个错误,应该以不同的方式处理这种types的行为(不使用ajax)。
  2. 返回一个redirect结果,而不是返回一个视图,其中包含JavaScript,在客户端进行redirect。

有没有人对#1有评论? 或者,如果#2是一个很好的解决scheme,那么“redirectJavaScript视图”是什么样的?

你可以使用JavascriptResult来实现这一点。

redirect:

 return JavaScript("window.location = 'http://www.google.co.uk'"); 

重新加载当前页面:

 return JavaScript("location.reload(true)"); 

看来是最简单的select。

您可以使用URL返回JSON,并在客户端使用JavaScript更改window.location。 我更喜欢这种方式,而不是从服务器调用JavaScript函数,我认为这是打破了问题的分离。

服务器端:

 return Json(new {result = "Redirect", url = Url.Action("ActionName", "ControllerName")}); 

客户端:

 if (response.result == 'Redirect') window.location = response.url; 

当然,你可以添加更多的逻辑,因为在服务器端可能会出现错误,在这种情况下,result属性可能会指出这种情况并避免redirect。

你试图产生的行为并不是最好的使用AJAX。 如果您只想更新页面的一部分,而不是完全redirect到某个其他页面,则AJAX最适合使用。 这确实打败了AJAX的全部目的。

我build议不要使用AJAX来描述你所描述的行为。

或者,您可以尝试使用jQuery Ajax,它将提交请求,然后在请求完成时指定callback。 在callback中,您可以确定它是失败还是成功,并在成功时redirect到另一个页面。 我发现jQuery的Ajax更容易使用,特别是因为我已经使用库来处理其他事情。

你可以在这里find关于jquery ajax的文档,但是语法如下:

 jQuery.ajax( options ) jQuery.get( url, data, callback, type) jQuery.getJSON( url, data, callback ) jQuery.getScript( url, callback ) jQuery.post( url, data, callback, type) 

虽然不优雅,在某些情况下适用于我。

调节器

 if (RedirectToPage) return PartialView("JavascriptRedirect", new JavascriptRedirectModel("http://www.google.com")); else ... return regular ajax partialview 

模型

  public JavascriptRedirectModel(string location) { Location = location; } public string Location { get; set; } 

/Views/Shared/JavascriptRedirect.cshtml

 @model Models.Shared.JavascriptRedirectModel <script type="text/javascript"> window.location = '@Model.Location'; </script> 

使用JavaScript一定会完成这项工作。

如果这更多的是你的风格,你也可以使用Content

例:

MVC控制器

 [HttpPost] public ActionResult AjaxMethod() { return Content(@"http://www.google.co.uk"); } 

使用Javascript

 $.ajax({ type: 'POST', url: '/AjaxMethod', success: function (redirect) { window.location = redirect; } }); 

您可以简单地使用下面的Ajax Success来编写代码:

  $.ajax({ type: "POST", url: '@Url.Action("GetUserList", "User")', data: { id: $("#UID").val() }, success: function (data) { window.location.href = '@Url.Action("Dashboard", "User")'; }, error: function () { $("#loader").fadeOut("slow"); } }); 

我需要这样做,因为我有一个Ajaxlogin表单。 当用户成功login时,我redirect到一个新页面,并结束以前的请求,因为另一个页面处理redirect回依赖方(因为它是一个STS SSO系统)。

不过,我也希望它能够在禁用javascript的情况下工作,作为中央login跳和所有,所以我想出了这个,

  public static string EnsureUrlEndsWithSlash(string url) { if (string.IsNullOrEmpty(url)) throw new ArgumentNullException("url"); if (!url.EndsWith("/")) return string.Concat(url, "/"); return url; } public static string GetQueryStringFromArray(KeyValuePair<string, string>[] values) { Dictionary<string, string> dValues = new Dictionary<string,string>(); foreach(var pair in values) dValues.Add(pair.Key, pair.Value); var array = (from key in dValues.Keys select string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(dValues[key]))).ToArray(); return "?" + string.Join("&", array); } public static void RedirectTo(this HttpRequestBase request, string url, params KeyValuePair<string, string>[] queryParameters) { string redirectUrl = string.Concat(EnsureUrlEndsWithSlash(url), GetQueryStringFromArray(queryParameters)); if (request.IsAjaxRequest()) HttpContext.Current.Response.Write(string.Format("<script type=\"text/javascript\">window.location='{0}';</script>", redirectUrl)); else HttpContext.Current.Response.Redirect(redirectUrl, true); } 

你可以简单地用$ .ajaxSetup做一些Ajax响应filter来input响应。 如果响应包含MVCredirect,则可以在JS端评估此expression式。 下面是JS的代码示例:

 $.ajaxSetup({ dataFilter: function (data, type) { if (data && typeof data == "string") { if (data.indexOf('window.location') > -1) { eval(data); } } return data; } }); 

如果数据是: “window.location ='/ Acount / Login'”,那么上面的filter会捕获并评估redirect。

我不满意约瑟的最好答案,而不是纠正正确的问题,他告诉说这是错误的用例。 实际上,有很多地方,例如,如果你将一个旧的代码转换成一个代码,并且你需要它,那么你需要它。 在编程方面,没有任何理由,因为它不仅是你编写所有坏的和好的开发者的代码,而且你必须并肩工作。 所以如果我不在ajax中编写redirect代码,我的开发人员可能会迫使我为它提供一个解决scheme。 就像我喜欢使用所有AMD模式的网站或mvc4,我的公司可以让我远离它一年。

那么现在我们来谈谈解决scheme。

我已经做了一个Ajax请求和响应处理,我发现最简单的方法是发送状态码给客户端,并有一个标准的JavaScript函数来理解这些代码。 如果我只是发送例如代码13,这可能意味着一个redirect。

所以,像{statusCode:13,messsage:'/ home / logged-in'}这样的json响应当然会有很多变化,像{status:'success',code:13,url:'/ home / logged-in ',消息:'你现在login'}

等等,所以你可以自己select标准的信息

通常我从基础控制器类inheritance,并把我这样的标准答案的select

 public JsonResult JsonDataResult(object data, string optionalMessage = "") { return Json(new { data = data, status = "success", message = optionalMessage }, JsonRequestBehavior.AllowGet); } public JsonResult JsonSuccessResult(string message) { return Json(new { data = "", status = "success", message = message }, JsonRequestBehavior.AllowGet); } public JsonResult JsonErrorResult(string message) { return Json(new { data = "", status = "error", message = message }, JsonRequestBehavior.AllowGet); } public JsonResult JsonRawResult(object data) { return Json(data, JsonRequestBehavior.AllowGet); } 

关于使用Ajax.BeginForm的$ .ajax intead我很喜欢使用jquery ajax,但是我做了,但是它不是我在全世界做决定我有一个Ajax.BeginForm应用程序,当然我没有这样做。 但我必须忍受它。

所以有一个成功的callback在开始的forms,你不需要使用jQuery的Ajax使用callback在这里的东西关于Ajax.BeginForm,调用操作,返回JSON,我如何访问我的OnSuccess JSfunction中的JSON对象?

谢谢

如果您是从JavaScript类redirect的

同一视图 – 不同的控制器

 <strike>window.location.href = `'Home'`;</strike> 

是不一样的看法

 <strike>window.location.href = `'Index/Home'`;</strike> 

添加一个帮手类:

 public static class Redirector { public static void RedirectTo(this Controller ct, string action) { UrlHelper urlHelper = new UrlHelper(ct.ControllerContext.RequestContext); ct.Response.Headers.Add("AjaxRedirectURL", urlHelper.Action(action)); } public static void RedirectTo(this Controller ct, string action, string controller) { UrlHelper urlHelper = new UrlHelper(ct.ControllerContext.RequestContext); ct.Response.Headers.Add("AjaxRedirectURL", urlHelper.Action(action, controller)); } public static void RedirectTo(this Controller ct, string action, string controller, object routeValues) { UrlHelper urlHelper = new UrlHelper(ct.ControllerContext.RequestContext); ct.Response.Headers.Add("AjaxRedirectURL", urlHelper.Action(action, controller, routeValues)); } } 

然后打电话给你的行动:

这个.RedirectTo(“Index”,“Cement”);

将javascript代码添加到任何全局JavaScript包含的文件或布局文件中以拦截所有的ajax请求:

 <script type="text/javascript"> $(function() { $(document).ajaxComplete(function (event, xhr, settings) { var urlHeader = xhr.getResponseHeader('AjaxRedirectURL'); if (urlHeader != null && urlHeader !== undefined) { window.location = xhr.getResponseHeader('AjaxRedirectURL'); } }); }); </script> 

正如本福斯特说,你可以返回的JavaScript,它会redirect到你想要的页面。

要在当前页面加载页面:

 return JavaScript("window.location = 'http://www.google.co.uk'");' 

要在新标签中加载页面:

 return JavaScript("window.open('http://www.google.co.uk')"); 

通过放入其中一个元刷新标签,您可以从ajax调用中获得非基于js的redirect。 这里似乎是工作: return Content("<meta http-equiv=\"refresh\" content=\"0;URL='" + @Url.Action("Index", "Home") + "'\" />");

注意:我发现Firefox的自动禁用元刷新,使得这不是很有用。

这个怎么样 :

 public ActionResult GetGrid() { string url = "login.html"; return new HttpStatusCodeResult(System.Net.HttpStatusCode.Redirect,url) } 

接着

 $(document).ajaxError(function (event, jqxhr, settings, thrownError) { if (jqxhr.status == 302) { location.href = jqxhr.statusText; } }); 

要么

 error: function (a, b, c) { if (a.status == 302) { location.href = a.statusText; } }