MVC Routing 限制Action

  • 473
  • 0
  • MVC
  • 2019-06-26

自訂類別限制Routing 比對條件

新增一個MVC的專案時,預設的RouteConfig 如下:

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

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

如果我要新增一組MapRoute,希望輸入 http://localhost:7432/About 的時候可以正常開啟http://localhost:7432/Home/About

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

		routes.MapRoute(
			name: "Test",
			url: "{action}/{id}",
			defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
			
			//方法一,直接在這邊限制比對的Action 為 "(About|Index|Contact)"
			//只有這三個Action 會會比對
			//constraints: new { action = "(About|Index|Contact)" }
			
			//方法二 實作IRouteConstraint介面來自訂的路由約束條件
			constraints: new { action = new ActionConstraint() }
			
		);

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

新增一個類別繼承 IRouteConstraint 並實作methodLMatch

/// <summary>
/// 只有 "About", "Index", "Contact" 這三個Action 會吃這個路由
/// </summary>
public class ActionConstraint : IRouteConstraint
{
	public bool Match(HttpContextBase httpContext, Route route, string parameterName,
		RouteValueDictionary values, RouteDirection routeDirection)
	{
		String[] constraintName = new String[] { "About", "Index", "Contact" };
		if (values.ContainsKey(parameterName))
		{
			var strValue = values[parameterName] as String;

			//不考慮大小寫的比對方式
			//return Array.Exists(constraintName, val => val.Equals(strValue, StringComparison.InvariantCultureIgnoreCase));

			//Linq
			return constraintName.Any(x => x.Equals(strValue));
		}
		return false;
	}
}