93

我正在使用 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. 要么我在构建这个错误并且应该以不同的方式处理这种类型的操作(不使用 ajax)。
  2. 与其返回重定向结果,不如返回一个视图,其中包含在客户端执行重定向的 javascript。

有人对#1 有意见吗?或者如果 #2 是一个很好的解决方案,那么“重定向 javascript 视图”会是什么样子?

4

15 回答 15

174

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

重定向:

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

重新加载当前页面:

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

似乎是最简单的选择。

于 2011-08-15T19:59:05.657 回答
35

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

服务器端:

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

客户端:

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

当然,您可以添加更多逻辑,因为服务器端可能存在错误,在这种情况下,结果属性可以指示这种情况并避免重定向。

于 2014-07-10T15:35:46.130 回答
15

虽然不优雅,但在某些情况下对我有用。

控制器

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>
于 2011-07-12T05:41:50.757 回答
13

您尝试产生的行为并不是最好使用 AJAX 完成。如果您只想更新页面的一部分,而不是完全重定向到其他页面,则最好使用 AJAX。这确实违背了 AJAX 的全部目的。

我建议不要将 AJAX 与您描述的行为一起使用。

或者,您可以尝试使用 jquery Ajax,它会提交请求,然后在请求完成时指定回调。在回调中,您可以确定它是失败还是成功,并在成功时重定向到另一个页面。我发现 jquery Ajax 更容易使用,尤其是因为我已经在使用该库来做其他事情了。

您可以在此处找到有关 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)
于 2009-10-08T15:28:20.333 回答
7

使用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;
    }
});
于 2015-03-16T21:58:20.313 回答
4

您可以简单地用 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");
            }
});
于 2016-09-08T14:14:24.460 回答
3

这个怎么样 :

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;
       }  
}
于 2017-04-28T11:44:52.927 回答
1

我对约瑟夫的最佳答案不满意,他没有解决正确的问题,而是告诉我这是错误的用例。实际上有很多地方,例如,如果您将旧代码库转换为 ajaxified 代码并且您需要它,那么您就需要它。在编程中没有任何借口,因为不仅是你在编写所有坏和好的开发人员,而且你必须并肩工作。因此,如果我不在 ajax 中编写重定向代码,我的开发人员同事可以强迫我找到解决方案。就像我喜欢使用所有 AMD 模式的站点或 mvc4 一样,我的公司可以让我远离它一年。

那么现在让我们谈谈解决方案。

我已经完成了 ajax 请求和响应处理,我发现最简单的方法是将状态代码发送到客户端并使用一个标准的 javascript 函数来理解这些代码。如果我只是发送例如代码 13,它可能意味着重定向。

因此,像 { statusCode: 13, messagesage: '/home/logged-in' } 这样的 json 响应当然有很多变化,例如 { status: 'success', code: 13, url: '/home/logged-in ', message: '你现在登录了' }

等等,所以取决于您自己选择的标准消息

通常我从基本 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 intead of Ajax.BeginForm 我很想使用 Jquery ajax 并且我确实这样做了,但再次由我来做决定我有一个充满 Ajax.BeginForm 的应用程序,当然我没有这样做。但我必须忍受它。

所以在开始表单中也有一个成功回调,你不需要使用 jquery ajax 来使用回调这里关于它的东西 Ajax.BeginForm,调用操作,返回 JSON,如何在我的 OnSuccess JS 函数中访问 JSON 对象?

谢谢

于 2012-04-29T06:08:06.017 回答
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);

    }
于 2014-07-28T19:23:46.167 回答
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'"上面的过滤器将捕获并评估以进行重定向。

于 2016-10-27T13:24:19.037 回答
0

如果您从 JavaScript 类重定向

相同的视图 - 不同的控制器

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

不一样的看法

<strike>window.location.href = `'Index/Home'`;</strike>
于 2013-12-22T15:01:03.657 回答
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("索引", "水泥");

将 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>

于 2015-08-24T09:30:11.213 回答
0

正如本福斯特所说,您可以返回 Javascript,它会将您重定向到所需的页面。

在当前页面加载页面:

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

要在新选项卡中加载页面:

return JavaScript("window.open('http://www.google.co.uk')");
于 2016-05-20T07:25:13.523 回答
0

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

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

于 2017-04-17T16:23:57.323 回答
0

接受的答案效果很好,除了 javascript 简短地显示在任何 ajax 目标元素中。为了解决这个问题,使用以下代码创建一个名为 _Redirect 的局部视图:

@model string
<script>
   window.location = '@Model';
</script>

然后,在控制器中替换

return Redirect(Url.Action("Index", "Home"));

return PartialView("_Redirect",Url.Action("Index", "Home"));

效果与接受的答案相同,但显示中没有简短的伪影。将 _Redirect.cshtml 放在共享文件夹中,以便可以在任何地方使用。

于 2021-01-29T01:14:12.820 回答