RedirectToAction 从一个控制器到另一个控制器
RedirectToAction from one controller to another
我有一个使用 Ajax 表单的登录页面。在调用的 Action 中,我想根据某些条件重定向到不同的 Controller / Action。现在,我并不担心这个,只是想让重定向正常工作。
似乎被一个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>
这里的问题出在 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);
我有一个使用 Ajax 表单的登录页面。在调用的 Action 中,我想根据某些条件重定向到不同的 Controller / Action。现在,我并不担心这个,只是想让重定向正常工作。
似乎被一个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>
这里的问题出在 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);