How to get an ASP.NET MVC Ajax response to redirect to new page instead of inserting view into UpdateTargetId?
我正在使用Ajax.BeginForm来创建一个表单,它将ajax回发到某个控制器操作,然后如果操作成功,用户应该被重定向到另一个页面(如果操作失败,那么将显示一个状态消息 AjaxOptions UpdateTargetId)。
1 2 3 4 5 6 7 |
如果删除成功,我将返回重定向结果:
1 2 3 4 5 6 | [Authorize] public ActionResult Delete(Int32 UserId) { UserRepository.DeleteUser(UserId); return Redirect(Url.Action("Index","Home")); } |
但是Home Controller Index视图已加载到UpdateTargetId中,因此我最终得到了页面中的页面。 我正在考虑的两件事:
错了,应该处理这种类型
行动不同(不使用ajax)。
结果,返回一个有的视图
它中的javascript
在客户端重定向。
有人对#1发表评论吗? 或者,如果#2是一个很好的解决方案,那么"重定向javascript视图"会是什么样子?
您可以使用
重定向:
1 | return JavaScript("window.location = 'http://www.google.co.uk'"); |
要重新加载当前页面:
1 | return JavaScript("location.reload(true)"); |
似乎是最简单的选择。
您可以使用URL返回JSON,并在客户端使用JavaScript更改window.location。我更喜欢这种方式,而不是从服务器调用JavaScript函数,我认为它打破了关注点的分离。
服务器端:
1 |
客户端:
1 2 | if (response.result == 'Redirect') window.location = response.url; |
当然,您可以添加更多逻辑,因为服务器端可能存在错误,在这种情况下,result属性可以指示这种情况并避免重定向。
您尝试生成的行为并不是最好使用AJAX完成的。如果您只想更新页面的一部分,而不是完全重定向到其他页面,则最好使用AJAX。这真的打败了AJAX的整个目的。
我建议不要将AJAX与你描述的行为一起使用。
或者,您可以尝试使用jquery Ajax,它将提交请求,然后在请求完成时指定回调。在回调中,您可以确定它是失败还是成功,并在成功时重定向到另一个页面。我发现jquery Ajax更容易使用,特别是因为我已经将这个库用于其他东西了。
你可以在这里找到关于jquery ajax的文档,但语法如下:
1 2 3 4 5 6 7 8 9 | jQuery.ajax( options ) jQuery.get( url, data, callback, type) jQuery.getJSON( url, data, callback ) jQuery.getScript( url, callback ) jQuery.post( url, data, callback, type) |
虽然不优雅,但在某些情况下适合我。
调节器
1 2 3 4 | if (RedirectToPage) return PartialView("JavascriptRedirect", new JavascriptRedirectModel("http://www.google.com")); else ... return regular ajax partialview |
模型
1 2 3 4 5 6 | public JavascriptRedirectModel(string location) { Location = location; } public string Location { get; set; } |
/Views/Shared/JavascriptRedirect.cshtml
1 2 3 4 | @model Models.Shared.JavascriptRedirectModel <script type="text/javascript"> window.location = '@Model.Location'; |
使用
如果这更符合你的风格,你也可以使用
例:
MVC控制器
1 2 3 4 5 | [HttpPost] public ActionResult AjaxMethod() { return Content(@"http://www.google.co.uk"); } |
使用Javascript
1 2 3 4 5 6 7 | $.ajax({ type: 'POST', url: '/AjaxMethod', success: function (redirect) { window.location = redirect; } }); |
你可以简单地写下Ajax Success,如下所示:
1 2 3 4 5 6 7 8 9 10 11 | $.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"); } }); |
这个怎么样 :
1 2 3 4 5 | public ActionResult GetGrid() { string url ="login.html"; return new HttpStatusCodeResult(System.Net.HttpStatusCode.Redirect,url) } |
然后
1 2 3 4 5 | $(document).ajaxError(function (event, jqxhr, settings, thrownError) { if (jqxhr.status == 302) { location.href = jqxhr.statusText; } }); |
要么
1 2 3 4 5 | error: function (a, b, c) { if (a.status == 302) { location.href = a.statusText; } } |
您可以使用$ .ajaxSetup简单地执行某种ajax响应过滤器来进行响应。如果响应包含MVC重定向,则可以在JS端评估此表达式。 JS的示例代码如下:
1 2 3 4 5 6 7 8 9 10 | $.ajaxSetup({ dataFilter: function (data, type) { if (data && typeof data =="string") { if (data.indexOf('window.location') > -1) { eval(data); } } return data; } }); |
如果数据是:"window.location ='/ Acount / Login'"上面的过滤器将捕获该值并进行评估以进行重定向。
我需要这样做,因为我有一个ajax登录表单。当用户成功登录时,我重定向到新页面并结束上一个请求,因为另一个页面处理重定向回依赖方(因为它是一个STS SSO系统)。
但是,我还希望它能够禁用javascript,作为中央登录跃点,所以我想出了这个,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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}';", redirectUrl)); else HttpContext.Current.Response.Redirect(redirectUrl, true); } |
您可以通过放入其中一个元刷新标记从ajax调用获得基于非js的重定向。这似乎在起作用:
return Content("");
注意:我发现Firefox会自动禁用元刷新,这使得它不是很有用。
正如本福斯特所说,你可以返回Javascripts,它会将你重定向到所需的页面。
要在当前页面中加载页面:
1 | return JavaScript("window.location = 'http://www.google.co.uk'");' |
要在新标签中加载页面:
1 | return JavaScript("window.open('http://www.google.co.uk')"); |
添加辅助类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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)); } } |
然后打电话给你的行动:
this.RedirectTo("索引","水泥");
将javascript代码添加到任何全局JavaScript包含的文件或布局文件中以拦截所有ajax请求:
1 2 3 4 5 6 7 8 9 10 | <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'); } }); }); |
如果您从JavaScript类重定向
相同的观点 - 不同的控制器
1 | <strike>window.location.href = `'Home'`;</strike> |
是不一样的看法
1 | <strike>window.location.href = `'Index/Home'`;</strike> |
我不满意约瑟夫的最佳答案,而不是解决正确的问题,他说这是错误的用例。实际上有很多地方例如,如果你将旧的代码库转换为ajaxified代码,你需要它,那么你需要它。在编程中没有任何借口,因为它不仅是你编写所有坏的和优秀的开发人员而且你必须并肩工作。因此,如果我不在ajax中编写重定向代码,我的开发人员可以强迫我为它提供解决方案。就像我喜欢使用所有AMD图案网站或mvc4一样,我的公司可以让我远离它一年。
现在让我们谈谈解决方案。
我已经完成了ajax请求和响应处理,我发现最简单的方法是将状态代码发送到客户端,并有一个标准的javascript函数来理解这些代码。如果我只是发送例如代码13,它可能意味着重定向。
所以像{statusCode:13,messsage:'/ home / logged-in'}这样的json响应
当然有很多变化提议像
{status:'success',代码:13,url:'/ home / logged-in',消息:'您现在登录'}
等等,这取决于您自己选择的标准消息
通常我从基类Controller类继承,并像我这样选择标准响应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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的应用程序,当然我没有这样做。但我必须忍受它。
所以在开始形式中也有成功的回调,你不需要使用jquery ajax来使用回调
关于它的一些事情
Ajax.BeginForm,Calls Action,返回JSON,如何访问OnSuccess JS函数中的JSON对象?
谢谢