【问题标题】:AngularJS hash url and MVC routingAngularJS 哈希 url 和 MVC 路由
【发布时间】:2016-07-06 10:41:16
【问题描述】:

我在导航到 URL 时遇到问题。我的默认页面设置为登录,我的应用程序 URL 是 http://localhost:12345/#/

这很好用,但用户可以通过两种方式登录应用程序

  1. 直接通过应用程序。
  2. 通过查询字符串获取用户名和密码。

当应用程序通过查询字符串记录时,url 类似于http://localhost:12345?auth=123654654656564/#/

我想从 URL 中删除 auth 值。我试图映射路由,但它不起作用。

routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}",
            defaults: new { controller = "Account", action = "Login"}
);

我还尝试创建一个返回 view 的操作结果

routes.MapRoute(
            name: "ActualDefault",
            url: "{controller}/{action}",
            defaults: new { controller = "Account", action = "LoginQuery" }
);

控制器:

 public ActionResult Login()
 {
     if (Request.QueryString.Count > 0 && Request.QueryString != null)
     {
         //validating
         return RedirectToAction("LoginQuery", "Account");
     }
     else
     {
         return View();
     }
 }
 public ActionResult LoginQuery()
 {
        return View("Index");
 }

以上代码删除了查询字符串,但 URL 将是 http://localhost:12345/Account/LoginQuery/#/

我只需要像http://localhost:12345/#/ 这样的网址。

【问题讨论】:

  • 不清楚您的要求。您没有将用户名和密码作为查询字符串发送到 GET 方法吗?
  • 如果QueryStringnullif (Request.QueryString.Count > 0 && Request.QueryString != null) 会抛出异常(那么你的方法是错误的)
  • 实际上用户可以通过登录页面直接登录,也可以从其他应用程序通过发送用户名和密码作为查询字符串登录
  • 我正在处理查询字符串和应用程序(从登录页面用户将输入用户名和密码)。如果查询字符串为空,则用户正在输入用户名和密码。
  • 查看所有 URL,我可以看到它不受 angularJS 的控制,即在 URL 之后添加 #/。我会遇到类似的问题。似乎最好从您的其他应用程序中控制它。

标签: angularjs asp.net-mvc url-routing asp.net-mvc-routing routeconfig


【解决方案1】:

通过查询字符串登录

如果我不指出这是一个非常糟糕的做法,我会疏忽大意。登录应用程序时应始终使用 HTTP POST,并在帖子正文中发送用户机密,而不是查询字符串。

请注意,您也可以使用纯 HTML(或通过 angularjs)创建表单来调用 MVC 操作方法,或者您可以通过 JavaScript 或其他编程语言进行 HTTP POST 来执行相同的操作。

查询字符串值被 MVC 路由完全忽略。但是您可以使自定义路由使用查询字符串值。

public class LoginViaQueryStringRoute : RouteBase
{
    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var path = httpContext.Request.Path;

        if (!string.IsNullOrEmpty(path))
        {
            // Don't handle URLs that have a path /controller/action
            return null;
        }

        var queryString = httpContext.Request.QueryString;

        if (!queryString.HasKeys())
        {
            // Don't handle the route if there is no query string.
            return null;
        }

        if (!queryString.AllKeys.Contains("username") && !queryString.AllKeys.Contains("password"))
        {
            // Don't handle the case where controller and action are missing.
            return null;
        }

        var routeData = new RouteData(this, new MvcRouteHandler());

        routeData.Values["controller"] = "Account";
        routeData.Values["action"] = "LoginQuery";
        routeData.Values["username"] = queryString["username"];
        routeData.Values["password"] = queryString["password"];

        return routeData;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        return null;
    }
}

用法

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.Add(new LoginViaQueryStringRoute());

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

此路由现在将匹配 http://localhost:12345/?username=foo&password=bar 并将其发送到您的 LoginQuery 操作方法。

通过http://localhost:12345/#/登录

目前尚不清楚您希望它如何工作。由于哈希标签之后的所有内容一般不会从浏览器发送到服务器,因此http://localhost:12345/#/ 等价于http://localhost:12345/。因此,您实际上是在说“我希望我的主页成为登录页面”。

在典型的 MVC 应用程序中,您会在主页上设置AuthorizeAttribute重定向用户到登录页面。用户登录后,他们将被重定向回主页(或通常是他们最初请求的任何安全页面)。

[Authorize]
public ActionResult Index()
{
    return View();
}

如果您希望您的所有应用程序受到保护,您可以全局注册AuthorizeAttribute,并在您的公共操作方法(例如登录和注册页面)上使用AllowAnonymousAttribute

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new AuthorizeAttribute());
        filters.Add(new HandleErrorAttribute());
    }
}

以及您的登录操作方法:

[AllowAnonymous]
public ActionResult Login()
{
    //...
}

[AllowAnonymous]
[HttpPost]
public ActionResult Login(LoginModel model)
{
    //...
}

[AllowAnonymous]
public ActionResult LoginQuery(string username, string password)
{
    //...
}

但是,这是一个典型的 MVC-only 应用程序。

如果您使用 Angular 制作 SPA,那么这可能是一个非常不同的故事。也就是说,您可能会在客户端切换视图而不进行 HTTP 302 重定向 到登录表单(也许它会是一个弹出窗口 - 谁知道)。关键是,如果没有任何关于如何设置客户端与 MVC 通信的详细信息,除了通常如何设置 MVC 以在多页应用程序中工作之外,不可能就为客户端设置 MVC 提供任何有用的建议.

注意:我可以告诉您,您的路由配置错误。 DefaultActualDefault 定义 不能 存在于同一路由配置 because the first match always wins 中,因此第一个将运行而另一个将永远不会运行。两个路由 URL 定义都将匹配 any 长度为 0、1 或 2 个段的 URL,因此路由表中的第一个将匹配,另一个将是无法访问的执行路径.

【讨论】:

  • 感谢您的详细解释。您能否建议我如何在 http 正文中发送凭据?实际上我将查询字符串从其他应用程序传递到此应用程序。那么我应该在哪里添加凭据详细信息?如何访问当前应用程序中的 http 正文。
  • 我添加了一些在 MVC 中发布的参考。但是,请注意大多数编程语言(包括 JavaScript)也支持 HTTP POST。
猜你喜欢
  • 2012-12-28
  • 2011-07-30
  • 1970-01-01
  • 2014-11-15
  • 2015-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多