RedirectToAction с одного контроллера на другой - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть страница входа, которая использует форму Ajax. В вызываемом действии я хочу перенаправить на другой контроллер / действие, основываясь на некоторых критериях. На данный момент я не беспокоюсь об этом, а просто пытаюсь заставить Redirect работать.

Это кажется сложным из-за 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>

1 Ответ

0 голосов
/ 30 апреля 2020

Проблема здесь в атрибуте AjaxAwareRedirectAttribute.

var result = filterContext.Result as RedirectResult;

В строке выше вы ожидаете получить RedirectResult. Однако всякий раз, когда вы вызываете метод RedirectToAction, выходной результат становится типа RedirectToRouteResult.

. Поэтому он не работает.

Вы можете либо настроить AjaxAwareRedirectAttribute, либо продолжить использовать простое перенаправление метод и передача аргумента в качестве параметров строки запроса. (в конце концов, это единственный способ передать параметры через перенаправление).

Вот упрощенное решение, которое вы можете использовать, если все еще хотите изменить атрибут: (пожалуйста, обратите внимание, что крайние случаи не рассматриваются и сам код должен быть немного изменен)

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);
...