【问题标题】:RedirectToAction from one controller to another从一个控制器到另一个控制器的 RedirectToAction
【发布时间】:2020-04-30 19:37:29
【问题描述】:

我有一个使用 Ajax 表单的登录页面。在调用的动作中,我想根据某些标准重定向到不同的控制器/动作。目前,我并不担心这一点,只是试图让重定向工作。

ActionFilterAttribute 好像很复杂:

public class AjaxAwareRedirectAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var result = filterContext.Result as RedirectResult;
        if (result != null && filterContext.HttpContext.Request.IsAjaxRequest())
        {
            string destinationUrl = UrlHelper.GenerateContentUrl(result.Url, filterContext.HttpContext);
            filterContext.Result = new JavaScriptResult()
            {
                Script = string.Format("window.location = '{0}';", destinationUrl)
            };
        }
    }
}

在登录页面控制器操作调用后触发

return RedirectToAction("Index", "TwoFactorAuthentication");

重定向被忽略并重新显示登录页面。

整个站点的许多地方都使用了 AjaxAwareRedirectAttribute 属性,所以我需要小心我对它做什么(如果有的话)。

如果我使用简单的

return Redirect("/en/authentication");

那么这似乎工作正常。但是,我也想像这样传递模型数据

return RedirectToAction("Index", "TwoFactorAuthentication", member);

我现在不确定我是否接近并走在正确的轨道上,还是完全错了!

这是一个 Umbraco 7 项目,如果这与它有任何关系的话。

编辑:

我是否需要在客户端检测/处理重定向?

这是 Ajax 表单

@using (Ajax.BeginForm("Login", "LoginSignup", null, options, null))

这些是选项

var options = new AjaxOptions
{
    HttpMethod = "POST",
    OnFailure = "ShowError",
    OnSuccess = "ShowSuccess",
    UpdateTargetId = "target1",
    InsertionMode = InsertionMode.Replace
};

以及相关的脚本

<script>
    function ShowError(response) {
        $("#feedback").show();
        $("#signupfeedback").show();
        $("#status").html("@Umbraco.Field("#Login.ScriptErrorPostingForm")");
    }

    function ShowSuccess(response, textStatus, xhr) {
        if (xhr.responseText.indexOf('window') == -1) {
            $("#feedback").show();
            $("#signupfeedback").show();
            $(".validation-summary-errors").hide();
        }
    }

    function ShowExternalLoginError() {
        $("#status").removeClass();
        $("#status").addClass("b_noteList");
        $("#status").html("@Umbraco.Field("#Login.ScriptErrorOccurred")");
    }

</script>

【问题讨论】:

  • 你是如何处理客户端的? Ajax 和重定向可能很棘手。
  • @KevinBBurns - 我已经用相关的 Ajax 详细信息更新了我的问题。

标签: c# asp.net-mvc controller umbraco7


【解决方案1】:

这里的问题在于 AjaxAwareRedirectAttribute 属性。

var result = filterContext.Result as RedirectResult;

在上面的行中,您希望收到RedirectResult。但是,无论何时调用RedirectToAction 方法,输出结果都会变成RedirectToRouteResult 类型。

这就是它不起作用的原因。

您可以调整 AjaxAwareRedirectAttribute 或继续使用简单的 Redirect 方法并将参数作为查询字符串参数传递。 (最终,这是通过重定向传递参数的唯一方法)。

如果您仍想更改属性,可以使用以下简化的解决方案:(请注意,未涵盖边缘情况,代码本身应稍作重构)

public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        string destination = null;
        if(filterContext.Result is RedirectResult redirect)
        {
            destination = redirect.Url;
        }
        else if (filterContext.Result is RedirectToRouteResult routeRedirect)
        {
            var action = (string)routeRedirect.RouteValues["Action"];
            var controller = (string)routeRedirect.RouteValues["Controller"];

            var helper = new UrlHelper(filterContext.RequestContext);
            destination = helper.Action(action, controller, routeRedirect.RouteValues);
        }

        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            string destinationUrl = UrlHelper.GenerateContentUrl(destination, filterContext.HttpContext);
            filterContext.Result = new JavaScriptResult()
            {
                Script = string.Format("window.location = '{0}';", destinationUrl)
            };
        }
    }

如果你不想碰公共代码:

var url = Url.Action("Action", "Controller" , new { data = "test" });
return Redirect(url);

【讨论】:

  • 我在想这就是问题所在,我就是不知道为什么!这解释了很多,谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-05-21
  • 2018-06-28
  • 1970-01-01
  • 2015-09-07
  • 2019-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多