准备好使用 uint 路由约束了吗?
ready to use uint route constraint?
我有一个 .NET Core Web API 项目,我的 ID 是从 1 开始的整数。在大多数示例中,我看到这样的东西
[HttpGet("{id:int}")]
public async Task<ActionResult<User>> GetUserByIdAsync([FromRoute] int id)
{
// ...
}
因为我知道 ID 必须大于 0,所以我还添加了 :min(1)
路由约束。但是,将整数数据类型更改为 uint
不是更好吗?路线将是
"{id:uint:min(1)}"
并且方法参数将变为
[FromRoute] uint id
但不幸的是,uint 约束不存在。我认为当不为 ID 使用 GUID 时,这是一个标准问题,因为数据库将自动生成从 1 开始的整数 ID。我尝试创建自己的路由约束:
在 Startup
文件中,我在 services.AddControllers()
之后将其添加到 ConfigureServices
方法中
services.Configure<RouteOptions>(routeOptions =>
{
routeOptions.ConstraintMap.Add("uint", typeof(UIntRouteConstraint));
});
并且路由约束本身非常简单
public class UIntRouteConstraint : IRouteConstraint
{
public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
{
if (httpContext == null)
throw new ArgumentNullException(nameof(httpContext));
if (route == null)
throw new ArgumentNullException(nameof(route));
if (routeKey == null)
throw new ArgumentNullException(nameof(routeKey));
if (values == null)
throw new ArgumentNullException(nameof(values));
if (values.TryGetValue(routeKey, out object routeValue))
{
// check if param is a uint
return UInt32.TryParse(routeValue.ToString(), out uint number);
}
return false;
}
}
在通过 id url 调用获取用户进行测试时,这似乎按预期工作。但是我不确定这个约束是否是防弹的,我之前是否需要那些空检查。
是否存在现成的 uint
路由约束?我想我不是唯一需要这个的人。
Does a ready to use uint route constraint exist?
没有
基于当前可用的文档。
The ASP.NET Core Constraints folder provides good examples of creating a constraints
引用Routing in ASP.NET Core: Custom route constraints
如果查看内置约束,您会发现它们遵循相似的格式并检查是否为空。
例如,在查看 IntRouteConstraint
之后,我注意到您的示例中没有一些检查。
有可能
values.TryGetValue(routeKey, out object routeValue)
可能导致 routeValue
为 null。
至于额外的空检查,理想情况下只需要检查打算在当前函数范围内使用的参数。
重构代码:
public class UIntRouteConstraint : IRouteConstraint {
public bool Match(HttpContext httpContext, IRouter route, string routeKey,
RouteValueDictionary values, RouteDirection routeDirection) {
if (routeKey == null)
throw new ArgumentNullException(nameof(routeKey));
if (values == null)
throw new ArgumentNullException(nameof(values));
if (values.TryGetValue(routeKey, out object routeValue) && routeValue != null) {
if (routeValue is uint)
return true;
string valueString = Convert.ToString(routeValue, CultureInfo.InvariantCulture);
return UInt32.TryParse(valueString, out uint _);
}
return false;
}
}
我有一个 .NET Core Web API 项目,我的 ID 是从 1 开始的整数。在大多数示例中,我看到这样的东西
[HttpGet("{id:int}")]
public async Task<ActionResult<User>> GetUserByIdAsync([FromRoute] int id)
{
// ...
}
因为我知道 ID 必须大于 0,所以我还添加了 :min(1)
路由约束。但是,将整数数据类型更改为 uint
不是更好吗?路线将是
"{id:uint:min(1)}"
并且方法参数将变为
[FromRoute] uint id
但不幸的是,uint 约束不存在。我认为当不为 ID 使用 GUID 时,这是一个标准问题,因为数据库将自动生成从 1 开始的整数 ID。我尝试创建自己的路由约束:
在 Startup
文件中,我在 services.AddControllers()
ConfigureServices
方法中
services.Configure<RouteOptions>(routeOptions =>
{
routeOptions.ConstraintMap.Add("uint", typeof(UIntRouteConstraint));
});
并且路由约束本身非常简单
public class UIntRouteConstraint : IRouteConstraint
{
public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
{
if (httpContext == null)
throw new ArgumentNullException(nameof(httpContext));
if (route == null)
throw new ArgumentNullException(nameof(route));
if (routeKey == null)
throw new ArgumentNullException(nameof(routeKey));
if (values == null)
throw new ArgumentNullException(nameof(values));
if (values.TryGetValue(routeKey, out object routeValue))
{
// check if param is a uint
return UInt32.TryParse(routeValue.ToString(), out uint number);
}
return false;
}
}
在通过 id url 调用获取用户进行测试时,这似乎按预期工作。但是我不确定这个约束是否是防弹的,我之前是否需要那些空检查。
是否存在现成的 uint
路由约束?我想我不是唯一需要这个的人。
Does a ready to use uint route constraint exist?
没有
基于当前可用的文档。
The ASP.NET Core Constraints folder provides good examples of creating a constraints
引用Routing in ASP.NET Core: Custom route constraints
如果查看内置约束,您会发现它们遵循相似的格式并检查是否为空。
例如,在查看 IntRouteConstraint
之后,我注意到您的示例中没有一些检查。
有可能
values.TryGetValue(routeKey, out object routeValue)
可能导致 routeValue
为 null。
至于额外的空检查,理想情况下只需要检查打算在当前函数范围内使用的参数。
重构代码:
public class UIntRouteConstraint : IRouteConstraint {
public bool Match(HttpContext httpContext, IRouter route, string routeKey,
RouteValueDictionary values, RouteDirection routeDirection) {
if (routeKey == null)
throw new ArgumentNullException(nameof(routeKey));
if (values == null)
throw new ArgumentNullException(nameof(values));
if (values.TryGetValue(routeKey, out object routeValue) && routeValue != null) {
if (routeValue is uint)
return true;
string valueString = Convert.ToString(routeValue, CultureInfo.InvariantCulture);
return UInt32.TryParse(valueString, out uint _);
}
return false;
}
}