我遇到了一个我不知道如何修复的问题。
我的问题的上下文是基于在会话变量丢失时将用户重定向到Login的需要。
我们正在做的是对预览执行操作的控制器操作进行修饰,验证名为[“SesionesPorUsuarios”]的会话变量,其中不同于null
这样的事情:
[HttpPost]
[IndicadorUltimaAccionDelSistema()]
public JsonResult ConsulteLosProductos(string elAliasDelTipoDeProducto)
{
//stuffs...
}
然后像这样:
public class IndicadorUltimaAccionDelSistema : ActionFilterAttribute
{
/stuffs...
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (HttpContext.Current.Session["SesionesPorUsuarios"] != null)
{
/stuffs...
}
else
{
/stuffs...
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "action", "Login" },
{ "controller", "Login" }
});
}
}
}
我们的登录操作是:
public ActionResult Login()
{
return View();
}
我们遇到了问题,当在$ .post()
等ajax方法中调用该操作时post方法获取操作“Login”返回的所有视图,但它不会将用户重定向到Login页面,post方法获取操作“Login”返回的所有html,并将其视为一个JSON对象。
任何人都知道我们如何解决这个问题,或者我们可以根据需要应用什么工作
...谢谢
答案 0 :(得分:4)
您必须检查它是否是ajax请求并将URL发送为json,并在客户端检查该param是否通过js从客户端重定向:
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 403;
filterContext.Result = new JsonResult { Data = "LogOut"};
}
else
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "action", "Login" },
{ "controller", "Login" }
});
}
并注册ajaxError事件并在该检查中查找值并重定向:
$(document).ajaxError(function(e, xhr, opts) {
if (xhr.status == 403 && xhr.responseText.indexOf("LogOut") != -1) {
window.location.href = "@Url.Action("Login", "Account")";
}
});
现在在任何ajax调用上如果session为null,用户将被重定向到登录操作。
您也可以返回一个对象而不是字符串@Shyju在帖子中演示,我使用字符串来保持简单:)
答案 1 :(得分:1)
您可以更新操作过滤器以检查请求是否来自ajax调用。如果是,则返回带有要重定向到的登录URL的json响应。您可以通过检查请求中的"X-Requested-With"
标头来确定它是否是ajax调用。对于ajax请求,值为"XmlHttpRequest"
public override void OnActionExecuting(ActionExecutingContext context)
{
if( YourCodeToCheckWhetherUserIsAuthenticatedHere()==false)
{
var url = new UrlHelper(context.Controller.ControllerContext.RequestContext)
.Action("Login", "Account");
if (context.HttpContext.Request.IsAjaxRequest())
{
context.Result = new JsonResult { Data = new { LoginUrl = url} };
}
//to do : Non ajax request. keep your existing code
}
}
现在,在$.post
方法的回调中,检查此数据并执行任何操作。
编辑:根据评论
如果您有许多地方正在进行ajax通话,则可以在全局ajaxComplete
事件中执行此操作。
$(function(){
$(document).ajaxComplete(function(a,xhr,c) {
if (xhr.status === 401) {
var d = $.parseJSON(xhr.responseText);
//alert("login failed"); // Let's redirect
window.location.href = d.LoginUrl;
}
});
});
Request.IsAjaxMethod()
检查X-Requested-With
标头值。如果您使用角度js的$http
服务来进行这些调用,则会使用此特定标头will not be available。在这种情况下,您需要专门将其添加到您的电话中。
var app= angular.module('yourApp', []);
app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
}]);
答案 2 :(得分:0)
我的朋友们,你们已经给了我们解决问题的答案,非常感谢你们。
我们用来解决问题的方法是:
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 403;
filterContext.Result = new JsonResult { Data = "LogOut" };
}
else {
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "action", "Login" },
{ "controller", "Login" }
});
}
并在全球js上查看:
$(function () {
$(document).ajaxComplete(function (a, xhr, c) {
if (xhr.status == 403 && xhr.responseText.indexOf("LogOut") != -1) {
window.location.href = "@Url.Action("Login", "Login")";
}
});
});
问题解决了,真的非常感谢。