我正在使用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]
}
如果删除成功,我将返回重定向结果:
[Authorize]
public ActionResult Delete(Int32 UserId)
{
UserRepository.DeleteUser(UserId);
return Redirect(Url.Action("Index", "Home"));
}
但是Home Controller Index视图已加载到UpdateTargetId中,因此我最终得到了页面中的页面。我正在考虑两件事:
有没有人对#1发表评论?或者如果#2是一个很好的解决方案,“重定向javascript视图”会是什么样的?
答案 0 :(得分:164)
您可以使用JavascriptResult
来实现此目标。
重定向:
return JavaScript("window.location = 'http://www.google.co.uk'");
要重新加载当前页面:
return JavaScript("location.reload(true)");
似乎是最简单的选择。
答案 1 :(得分:21)
您可以使用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属性可以指示这种情况并避免重定向。
答案 2 :(得分:12)
您尝试生成的行为并不是最好使用AJAX完成的。如果您只想更新页面的一部分,而不是完全重定向到其他页面,则最好使用AJAX。这真的打败了AJAX的整个目的。
我建议不要将AJAX用于你所描述的行为。
或者,您可以尝试使用jquery Ajax,它将提交请求,然后在请求完成时指定回调。在回调中,您可以确定它是失败还是成功,并在成功时重定向到另一个页面。我发现jquery Ajax更容易使用,特别是因为我已经将这个库用于其他事情了。
您可以找到有关jquery ajax here的文档,但语法如下:
jQuery.ajax( options )
jQuery.get( url, data, callback, type)
jQuery.getJSON( url, data, callback )
jQuery.getScript( url, callback )
jQuery.post( url, data, callback, type)
答案 3 :(得分:11)
虽然不优雅,但在某些情况下适合我。
<强>控制器强>
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>
答案 4 :(得分:5)
使用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;
}
});
答案 5 :(得分:3)
你可以简单地写下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");
}
});
答案 6 :(得分:1)
我需要这样做,因为我有一个ajax登录表单。当用户成功登录时,我重定向到新页面并结束上一个请求,因为另一个页面处理重定向回依赖方(因为它是一个STS SSO系统)。
但是,我也希望它能够禁用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);
}
答案 7 :(得分:1)
您可以使用 $。ajaxSetup 简单地执行某种ajax响应过滤器以进行响应。如果响应包含MVC重定向,则可以在JS端评估此表达式。以下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'”上面的过滤器会捕获并评估以进行重定向。
答案 8 :(得分:1)
这个怎么样:
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;
}
}
答案 9 :(得分:0)
现在让我们谈谈解决方案。
我已经完成了ajax请求和响应处理,我发现最简单的方法是将状态代码发送到客户端,并有一个标准的javascript函数来理解这些代码。如果我只是发送例如代码13,它可能意味着重定向。
所以像{statusCode:13,messsage:'/ home / logged-in'}这样的json响应 当然有很多变化提议像 {status:'success',代码:13,url:'/ home / logged-in',消息:'您现在登录'}
等,这取决于您自己选择的标准消息
通常我从基类Controller类继承并选择像这样的标准响应
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的应用程序,当然我没有这样做。但我必须忍受它。
所以在begin表单中也有成功的回调,你不需要使用jquery ajax来使用回调 关于它的一些事情 Ajax.BeginForm, Calls Action, Returns JSON, How do I access JSON object in my OnSuccess JS Function?
由于
答案 10 :(得分:0)
如果你是从JavaScript类重定向相同的视图 - 不同的控制器
<strike>window.location.href = `'Home'`;</strike>
不是同一个视图
<strike>window.location.href = `'Index/Home'`;</strike>
答案 11 :(得分:0)
添加帮助程序类:
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(“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>
答案 12 :(得分:0)
正如本福斯特所说,您可以返回Javascripts,它会将您重定向到所需的页面。
要在当前页面中加载页面:
return JavaScript("window.location = 'http://www.google.co.uk'");'
要在新标签页中加载页面:
return JavaScript("window.open('http://www.google.co.uk')");
答案 13 :(得分:0)
您可以通过放入其中一个元刷新标记,从ajax调用中获取非基于js的重定向。这似乎在起作用:
return Content("<meta http-equiv=\"refresh\" content=\"0;URL='" + @Url.Action("Index", "Home") + "'\" />");
注意:我发现Firefox会自动禁用元刷新,这使得它不是很有用。
答案 14 :(得分:0)
接受的答案效果很好,除了在 ajax 目标元素中短暂显示 javascript 之外。要解决此问题,请使用以下代码创建一个名为 _Redirect 的局部视图:
@model string
<script>
window.location = '@Model';
</script>
然后,在控制器中替换
return Redirect(Url.Action("Index", "Home"));
与
return PartialView("_Redirect",Url.Action("Index", "Home"));
效果与接受的答案相同,但没有显示中的简短伪影。将 _Redirect.cshtml 放在共享文件夹中,以便从任何地方使用。