C# 如何让 ASP.NET MVC Ajax 响应重定向到新页面而不是将视图插入到 UpdateTargetId 中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1538523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get an ASP.NET MVC Ajax response to redirect to new page instead of inserting view into UpdateTargetId?
提问by Jeff Widmer
I am using the Ajax.BeginForm to create a form the will do an ajax postback to a certain controller action and then if the action is successful, the user should get redirected to another page (if the action fails then a status message gets displayed using the AjaxOptions UpdateTargetId).
我正在使用 Ajax.BeginForm 创建一个表单,该表单将对某个控制器操作执行 ajax 回发,然后如果操作成功,用户应该被重定向到另一个页面(如果操作失败,则使用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]
}
If the delete is successful I am returning a Redirect result:
如果删除成功,我将返回重定向结果:
[Authorize]
public ActionResult Delete(Int32 UserId)
{
UserRepository.DeleteUser(UserId);
return Redirect(Url.Action("Index", "Home"));
}
But the Home Controller Index view is getting loaded into the UpdateTargetId and therefore I end up with a page within a page. Two things I am thinking about:
但是 Home Controller Index 视图正在加载到 UpdateTargetId 中,因此我最终得到了一个页面中的一个页面。我在想两件事:
- Either I am architecting this wrong and should handle this type of action differently (not using ajax).
- Instead of returning a Redirect result, return a view which has javascript in it that does the redirect on the client side.
- 要么我构建这个错误,应该以不同的方式处理这种类型的操作(不使用 ajax)。
- 不是返回重定向结果,而是返回一个包含 javascript 的视图,该视图在客户端执行重定向。
Does anyone have comments on #1? Or if #2 is a good solution, what would the "redirect javascript view" look like?
有人对#1有意见吗?或者,如果 #2 是一个很好的解决方案,那么“重定向 javascript 视图”会是什么样子?
采纳答案by Ben Foster
You can use JavascriptResult
to achieve this.
您可以使用它JavascriptResult
来实现这一点。
To redirect:
重定向:
return JavaScript("window.location = 'http://www.google.co.uk'");
To reload the current page:
要重新加载当前页面:
return JavaScript("location.reload(true)");
Seems the simplest option.
似乎是最简单的选择。
回答by Joseph
The behavior you're trying to produce is not really best done using AJAX. AJAX would be best used if you wanted to only update a portion of the page, not completely redirect to some other page. That defeats the whole purpose of AJAX really.
您试图产生的行为并不是使用 AJAX 来最好地完成的。如果您只想更新页面的一部分,而不是完全重定向到其他页面,则最好使用 AJAX。这真的违背了 AJAX 的全部目的。
I would suggest to just not use AJAX with the behavior you're describing.
我建议不要将 AJAX 与您所描述的行为一起使用。
Alternatively, you could try using jquery Ajax, which would submit the request and then you specify a callback when the request completes. In the callback you could determine if it failed or succeeded, and redirect to another page on success. I've found jquery Ajax to be much easier to use, especially since I'm already using the library for other things anyway.
或者,您可以尝试使用 jquery Ajax,它会提交请求,然后在请求完成时指定回调。在回调中,您可以确定它是失败还是成功,并在成功时重定向到另一个页面。我发现 jquery Ajax 更容易使用,尤其是因为我已经将库用于其他用途。
You can find documentation about jquery ajax here, but the syntax is as follows:
您可以在此处找到有关 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)
回答by Valamas
While not elegant, works for me in certain situations.
虽然不优雅,但在某些情况下对我有用。
Controller
控制器
if (RedirectToPage)
return PartialView("JavascriptRedirect", new JavascriptRedirectModel("http://www.google.com"));
else
... return regular ajax partialview
Model
模型
public JavascriptRedirectModel(string location)
{
Location = location;
}
public string Location { get; set; }
/Views/Shared/JavascriptRedirect.cshtml
/Views/Shared/JavascriptRedirect.cshtml
@model Models.Shared.JavascriptRedirectModel
<script type="text/javascript">
window.location = '@Model.Location';
</script>
回答by Asif Ashraf
I m not satisfied by the best answer by the Joseph, instead of fixing the correct problem, he told that this is wrong use case. In fact there are many places for example if you are converting an old codebase to ajaxified code and there you NEED it, then you NEED it. In programming there is no excuse because its not only you who is coding its all bad and good developers and you have to work side by side. So if I don't code redirection in ajax my fellow developer can force me to have a solution for it. Just like I like to use all AMD patterned sites or mvc4, and my company can keep me away from it for a year.
我对约瑟夫的最佳答案不满意,他没有解决正确的问题,而是说这是错误的用例。实际上有很多地方,例如,如果您将旧代码库转换为ajaxified 代码,并且您需要它,那么您就需要它。在编程中没有任何借口,因为不仅仅是你自己在编码,所有好的和坏的开发人员都必须并肩工作。因此,如果我不在 ajax 中编写重定向代码,我的开发伙伴可以强迫我找到解决方案。就像我喜欢使用所有 AMD 模式的网站或 mvc4 一样,我的公司可以让我远离它一年。
So let's talk on the solution now.
所以现在让我们谈谈解决方案。
I have done hell heck of ajax request and response handling and the simplest way I found out was to send status codes to the client and have one standard javascript function to understand those codes. If i simply send for example code 13 it might meant a redirect.
我已经完成了 ajax 请求和响应处理的地狱,我发现的最简单的方法是将状态代码发送到客户端并使用一个标准的 javascript 函数来理解这些代码。如果我只是发送例如代码 13,则可能意味着重定向。
So a json response like { statusCode: 13, messsage: '/home/logged-in' } of course there are tons of variations proposed like { status: 'success', code: 13, url: '/home/logged-in', message: 'You are logged in now' }
因此,像 { statusCode: 13, message: '/home/logged-in' } 这样的 json 响应当然有很多变体,例如 { status: 'success', code: 13, url: '/home/logged-in ', message: '您现在已登录' }
etc , so up to your own choice of standard messages
等等,所以取决于您自己选择的标准消息
Usually I Inherit from base Controller class and put my choice of standard responses like this
通常我从基控制器类继承并把我选择的标准响应放在这样的位置
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);
}
About using $.ajax intead of Ajax.BeginForm I would love to use Jquery ajax and I do, but again its not me in the whole world to make decisions I have an application full of Ajax.BeginForm and of course I didnt do that. But i have to live with it.
关于使用 $.ajax 而不是 Ajax.BeginForm 我很想使用 Jquery ajax,我也这样做了,但在整个世界中,我又不是我来做决定的,我有一个充满 Ajax.BeginForm 的应用程序,当然我没有这样做。但我必须忍受它。
So There is a success callback in begin form too, you don't need to use jquery ajax to use callbacks Something about it here Ajax.BeginForm, Calls Action, Returns JSON, How do I access JSON object in my OnSuccess JS Function?
所以开始形式也有一个成功回调,你不需要使用 jquery ajax 来使用回调这里有一些关于它的东西 Ajax.BeginForm,调用操作,返回 JSON,如何在我的 OnSuccess JS 函数中访问 JSON 对象?
Thanks
谢谢
回答by aslanpayi
If you're redirect from the JavaScript class
如果您从 JavaScript 类重定向
same view - diferent controller
相同的视图 - 不同的控制器
<strike>window.location.href = `'Home'`;</strike>
is not same view
不一样的看法
<strike>window.location.href = `'Index/Home'`;</strike>
回答by Francisco Goldenstein
You can return a JSON with the URL and change the window.location using JavaScript at client side. I prefer this way than calling a JavaScript function from the server, which I think that it's breaking the separation of concerns.
您可以返回带有 URL 的 JSON,并在客户端使用 JavaScript 更改 window.location。我更喜欢这种方式而不是从服务器调用 JavaScript 函数,我认为它打破了关注点的分离。
Server side:
服务器端:
return Json(new {result = "Redirect", url = Url.Action("ActionName", "ControllerName")});
Client side:
客户端:
if (response.result == 'Redirect')
window.location = response.url;
Of course you can add more logic because there could be an error on the server side and in that case the result property could indicate this situation and avoid the redirection.
当然,您可以添加更多逻辑,因为服务器端可能会出现错误,在这种情况下,结果属性可以指示这种情况并避免重定向。
回答by Ryan Mann
I needed to do this because I have an ajax login form. When users login successfully I redirect to a new page and end the previous request because the other page handles redirecting back to the relying party (because it's a STS SSO System).
我需要这样做,因为我有一个 ajax 登录表单。当用户成功登录时,我重定向到一个新页面并结束前一个请求,因为另一个页面处理重定向回依赖方(因为它是一个 STS SSO 系统)。
However, I also wanted it to work with javascript disabled, being the central login hop and all, so I came up with this,
但是,我也希望它在禁用 javascript 的情况下工作,作为中央登录跃点等等,所以我想出了这个,
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);
}
回答by christo8989
Using JavaScript
will definitely do the job.
使用JavaScript
肯定会完成这项工作。
You can also use Content
if this is more your style.
Content
如果这更符合您的风格,您也可以使用。
Example:
例子:
MVC Controller
MVC控制器
[HttpPost]
public ActionResult AjaxMethod()
{
return Content(@"http://www.google.co.uk");
}
Javascript
Javascript
$.ajax({
type: 'POST',
url: '/AjaxMethod',
success: function (redirect) {
window.location = redirect;
}
});
回答by faisale
Add a helper class:
添加一个辅助类:
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));
}
}
Then call in your action:
然后调用您的操作:
this.RedirectTo("Index", "Cement");
this.RedirectTo("索引", "水泥");
Add javascript code to any global javascript included file or layout file to intercept all ajax requests:
将 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>
回答by Trilok Pathak
As ben foster says you can return the Javascripts and it will redirect you to the desired page.
正如本福斯特所说,您可以返回 Javascript,它会将您重定向到所需的页面。
To load page in the current page:
在当前页面加载页面:
return JavaScript("window.location = 'http://www.google.co.uk'");'
To load page in the new tab:
要在新选项卡中加载页面:
return JavaScript("window.open('http://www.google.co.uk')");