2

我有一个区域是移动布局。然后,我的路线中也有只使用普通网站布局的控制器。

问题是当我使用 [Authorize(Roles = "ROLENAME")] 并且用户没有角色时,页面(移动站点)被重定向到正常的网站登录页面而不是移动页面。

是否可以根据用户尝试访问站点的区域在登录之间切换?

我尝试在我的区域 web.config 中添加以下内容,但没有奏效:

<authentication mode="Forms">
      <forms loginUrl="~/Activation/Login/Index" timeout="2880" />
</authentication>

有什么建议么?

4

1 回答 1

2

当您登录 Action 时,请检查它们是否在移动设备上,如果是,则重定向到移动登录页面。

private static string[] mobileDevices = new string[] {"iphone","ppc",
                                                      "windows ce","blackberry",
                                                      "opera mini","mobile","palm",
                                                      "portable","opera mobi" };

public static bool IsMobileDevice(string userAgent)  
{  
    // TODO: null check
    userAgent = userAgent.ToLower();  
    return mobileDevices.Any(x => userAgent.Contains(x));
}

然后在您的操作中:

public ActionResult Index()
{
    if (MobileHelper.IsMobileDevice(Request.UserAgent))
    {
        // Send to mobile route.
         return RedirectToAction("Login", "MobileActivation");
    }

    // Otherwise do normal login
}

编辑:

如果您想在您的应用程序中广泛应用它,您可以执行以下操作。

创建一个可以在任何地方应用的 ActionFilter,如下所示:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class RedirectToMobileArea : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var rd = filterContext.HttpContext.Request.RequestContext.RouteData;
        var currentAction = rd.GetRequiredString("action");
        var currentController = rd.GetRequiredString("controller");
        string currentArea = rd.Values["area"] as string;

        if (!currentArea.Equals("mobile", StringComparison.OrdinalIgnoreCase) && MobileHelper.IsMobileDevice(Request.UserAgent))
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "controller", currentController }, { "action", currentAction }, { "area", "mobile" } });
        }
    }
}

此过滤器将执行任何操作检查其是否已移动(并且尚未在移动区域中)并将其发送到移动区域中的相同操作和控制器。注意如果您使用同名控制器,则必须使用控制器命名空间注册您的路由,请参阅此答案

然后,您可以将过滤器应用于每个操作,例如:

[RedirectToMobileArea]
public ActionResult Index()
{
// do stuff.
}

或者,如果您想在任何地方执行此操作,请创建一个所有控制器都继承自的 BaseController 并将其应用于该控制器:

[RedirectToMobileArea]
public abstract class BaseController : Controller {

}

然后继承它:

public HomeController : BaseController {

}

我还没有测试过这些,但它应该可以工作......

于 2013-06-15T19:23:30.103 回答