
在ASP.NET Core中,路由是将传入的URL请求映射到正确的控制器和操作的方法。Attribute路由是一种基于属性,用于定义路由规则的方式,通过在控制器类和操作方法上应用特定的属性,来定义URL模板。
传统路由和属性路由(Attribute Routing)是ASP.NET Core中的两种主要路由(Routing)方式。下面是它们的比较和选择:
在ASP.NET Core中,我们可以在控制器类上使用[Route]属性来定义控制器级别的路由规则。以下是一个示例:
[Route("api/[controller]")]
public class UsersController : Controller
{
[HttpGet]
public IActionResult Get()
{
return Ok();
}
[HttpGet("{id}")]
public IActionResult Get(int id)
{
return Ok();
}
// ...
}在上面的示例中,我们在UsersController类上使用了[Route("api/[controller]")]属性,这表示所有该控制器的操作方法都可以通过“api/users”路径访问。
Tip:这里的
[controller]是一个占位符,它会被实际的控制器名称替换。例如,如果你访问api/users路径,[controller]将被替换为Users。
此外,我们还分别在Get和Get(int id)方法上使用了[HttpGet]和[HttpGet("{id}")]属性来定义它们的路由。其中,[HttpGet]表示该方法可以通过HTTP GET请求访问,而[HttpGet("{id}")]表示该方法可以通过具有id参数的HTTP GET请求访问。
通过这种方式,我们可以方便地定义控制器级别的路由规则,从而更好地组织我们的代码和URL。
在ASP.NET Core中,我们可以在操作方法上使用[Route]属性来定义操作方法级别的路由规则。以下是一个示例:
public class UsersController : Controller
{
[HttpGet("{id:int}")]
public IActionResult GetUser(int id)
{
// ...
}
[HttpPost]
[Route("users/create")]
public IActionResult CreateUser(UserViewModel model)
{
// ...
}
// ...
}在上面的示例中,我们在GetUser方法上使用了[HttpGet("{id:int}")]属性,这表示该方法可以通过具有id参数的HTTP GET请求访问,并且id必须是整数类型。而在CreateUser方法上,我们使用了[HttpPost]和[Route("users/create")]属性。这表示该方法可以通过HTTP POST请求访问,并且可以通过“users/create”路径访问。
通过这种方式,我们可以更加精细地定义操作方法级别的路由规则,从而更好地满足我们的需求。注意,操作方法级别的路由规则会覆盖控制器级别的路由规则。如果一个操作方法上定义了路由规则,它将优先于控制器级别的路由规则。
在ASP.NET Core中,我们可以使用自定义路由来实现更加灵活的路由规则。以下是一个示例:
public class CustomRouteAttribute : Attribute, IConfigureRoute
{
public string RouteName { get; set; }
public string[] RouteNames { get; set; }
public string Template { get; set; }
public object[] Constraints { get; set; }
public string[] Order { get; set; }
public void Configure(RouteCollection routes, string routeName)
{
var route = new Route(Template, new CustomRouteHandler());
if (Constraints != null)
{
foreach (var constraint in Constraints)
{
route.Constraints.Add(constraint.GetType().Name, constraint);
}
}
if (Order != null)
{
var routeList = new List<Route>();
foreach (var name in RouteNames)
{
var r = routes.GetRouteData(new MvcContext(HttpContext.Current));
while (r != null)
{
if (r.Route.RouteName.Equals(name, StringComparison.OrdinalIgnoreCase))
{
routeList.Add(r.Route);
break;
}
r = r.Route.Parent;
}
}
if (routeList.Count > 0)
{
var index = routeList.IndexOf(route);
if (index >= 0)
{
routeList.RemoveAt(index);
routeList.Insert(index, route);
}
}
else
{
routes.Add(route);
}
}
else
{
routes.Add(route);
}
}
}
[CustomRoute(RouteName = "custom", Template = "custom/{id}")]
public class CustomController : Controller
{
public IActionResult Index()
{
return View();
}
}在上面的示例中,我们自定义了一个CustomRouteAttribute属性,并在CustomController上使用它来定义路由规则。该属性的Template属性定义了路由模板,RouteName属性定义了路由名称,还可以定义其他的路由约束和路由顺序等。在Configure方法中,我们通过RouteCollection和RouteName来添加路由规则,并且可以根据需要对路由规则进行排序。
通过这种方式,我们可以更加灵活地定义路由规则,从而更好地满足我们的需求。注意,在使用自定义路由时,需要将UseMvc替换为UseMvcWithDefaultRoute,并且需要在Startup.cs文件的ConfigureServices方法中注册自定义路由。
在 ASP.NET Core 中,我们可以使用 Attribute 路由来定义路由参数。这可以让我们更精确地控制路由的生成。 下面是一个基本的例子:
[Route("api/[controller]")]
public class UsersController : Controller
{
[HttpGet("{id:int}")]
public IActionResult GetUser(int id)
{
// ...
}
}在这个例子中,[Route("api/[controller]")]是控制器级别的路由,表示所有 UsersController 的操作都会被路由到 “api/users” 路径。[HttpGet("{id:int}")]是操作级别的路由,表示 GetUser 方法可以被通过 GET 请求访问,并且需要一个整数参数 “id”。
你可以使用不同的 HTTP 方法来定义路由,例如:
[HttpGet("{id:int}")]
public IActionResult GetUser(int id)
{
// ...
}
[HttpPost]
public IActionResult CreateUser(UserModel model)
{
// ...
}在上面的例子中,[HttpPost]表示 CreateUser 方法只能通过 POST 请求访问。
你还可以使用自定义的路由约束来限制路由参数的取值范围,例如:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
public class PositiveIntConstraint : Attribute, IHttpRouteConstraint
{
public bool Match(HttpContext context, RouteData data, string parameterName, out RouteValueDictionary values)
{
var value = data.Values[parameterName];
if (value != null && value.ToString().IsInt() && Convert.ToInt32(value) > 0)
{
values = new RouteValueDictionary(new { });
return true;
}
return false;
}
}
public class UsersController : Controller
{
[HttpGet("{id}", Name = "GetUserById")]
[PositiveIntConstraint]
public IActionResult GetUser(int id)
{
// ...
}
}在上面的例子中,PositiveIntConstraint是一个自定义的路由约束,它限制了路由参数 “id” 必须是一个大于 0 的整数。如果不符合这个条件,路由请求将会失败。
除了上述的路由参数,Attribute 路由还有其他一些高级功能,包括:
[Route("{controller}/{action}/{id}")]。[Route("products/{id:int?}")],这里 id 是可选的。[Route("{controller=Home}/{action=Index}/{id=0}")],这里 controller 的默认值是 Home,action 的默认值是 Index,id 的默认值是 0。[HttpGet("{id:guid}")] 可以约束 id 必须是 GUID 类型。[Route("{category}/{product}")],这里 category 和 product 都是路由参数。[Route("/about")] 和 [Route("{id}")] 可以同时存在。好的,以下是一个综合了前面所有内容的示例:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
public class PositiveIntConstraint : Attribute, IHttpRouteConstraint
{
public bool Match(HttpContext context, RouteData data, string parameterName, out RouteValueDictionary values)
{
var value = data.Values[parameterName];
if (value != null && value.ToString().IsInt() && Convert.ToInt32(value) > 0)
{
values = new RouteValueDictionary(new { });
return true;
}
return false;
}
}
public class UsersController : Controller
{
[HttpGet("{id}", Name = "GetUserById")]
[PositiveIntConstraint]
public IActionResult GetUser(int id)
{
// ...
}
[HttpGet("users/edit/{id:guid}")]
public IActionResult EditUser(Guid id)
{
// ...
}
[HttpPost]
[Route("users/create")]
public IActionResult CreateUser(UserModel model)
{
// ...
}
[Route("users/deleted/{id}")]
public IActionResult DeleteUser(int id)
{
// ...
}
[Route("users/restore/{id}")]
public IActionResult RestoreUser(int id)
{
// ...
}
[Route("{*url}", Name = "PageNotFound")]
public IActionResult PageNotFound()
{
// ...
}
}在上面的例子中,我们定义了一个 PositiveIntConstraint 约束来限制路由参数必须是一个大于 0 的整数。我们定义了 5 个不同的路由:
GetUser 方法可以通过 /users/123 这样的 URL 访问,其中 123 是一个大于 0 的整数。EditUser 方法可以通过 /users/edit/456 这样的 URL 访问,其中 456 是一个 GUID 类型的参数。CreateUser 方法可以通过 /users/create 这样的 URL 访问,不需要任何参数。DeleteUser 方法可以通过 /users/deleted/789 这样的 URL 访问,其中 789 是一个大于 0 的整数。RestoreUser 方法可以通过 /users/restore/1000 这样的 URL 访问,其中 1000 是一个大于 0 的整数。PageNotFound 方法的结果,这个方法会返回一个 404 页面。Attribute路由是一种强大的路由机制,允许我们在 ASP.NET Core 中灵活地定义路由。通过使用各种属性和约束,我们可以精确控制 URL 的生成和解析。Attribute 路由提供了路由参数、可选参数、默认值、约束类型、自定义约束、嵌套路由、静态和动态路由等高级功能。这使得我们能够构建复杂而强大的 Web 应用程序,同时也提高了代码的可读性和可维护性。通过合理地使用 Attribute 路由,我们可以提升 Web 应用程序的性能和用户体验。