本文介绍了准备好使用 uint 路由约束了吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 .NET Core Web API 项目,我的 Id 是从 1 开始的整数.在大多数示例中,我看到的是这样的

I have a .NET Core Web API project and my Ids are integers starting at 1. In most samples I see something like this

[HttpGet("{id:int}")]
public async Task<ActionResult<User>> GetUserByIdAsync([FromRoute] int id)
{
    // ...
}

因为我知道 Ids 必须大于 0,所以我还添加了 :min(1) 路由约束.但是将整数数据类型更改为 uint 不是更好吗?路线将是

Since I know Ids must be greater than 0 I also added the :min(1) route constraint. But wouldn't it be better to change the integer datatype to uint? The route would then be

"{id:uint:min(1)}"

并且方法参数将更改为

[FromRoute] uint id

但不幸的是,uint 约束不存在.我认为当不为 Id 使用 GUID 时,这是一个标准问题,因为数据库将自动生成从 1 开始的整数 Id.我尝试创建自己的路由约束:

but unfortunately the uint constraint does not exist. I think when not using GUIDs for Ids this is a standard problem because databases will autogenerate integer Ids starting at 1. I tried to create my own route constraint:

Startup 文件中,我将其添加到 services.AddControllers()

In the Startup file I added this to the ConfigureServices method after services.AddControllers()

services.Configure<RouteOptions>(routeOptions =>
{
    routeOptions.ConstraintMap.Add("uint", typeof(UIntRouteConstraint));
});

而且路线约束本身非常简单

and the route constraint itself is pretty straight forward

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 调用 get 用户进行测试时,这似乎按预期工作.但我不确定这个约束是否是防弹的,我之前是否需要那些空检查.

This seems to work as expected when testing it by calling the get user by id url. But I'm not sure if this constraint is bullet proof and if I need those null checks before.

是否存在随时可用的uint 路由约束?我想我不是唯一需要这个的人.

Does a ready to use uint route constraint exist? I think I'm not the only one needing this.

推荐答案

没有

基于当前可用的文档.

ASP.NET Core 约束 文件夹提供了创建约束的好例子

参考 ASP.NET Core 中的路由:自定义路由约束

如果您查看内置约束,您会发现它们遵循类似的格式并检查是否为空.

If you review the built in constraints you will see that they follow similar formats and checks for null.

查看后IntRouteConstraint,例如,我注意到您的示例中没有的一些检查.

After reviewing IntRouteConstraint, for example, I noticed some checks that were not in your example.

有可能

values.TryGetValue(routeKey, out object routeValue)

可能导致 routeValuenull.

对于额外的空值检查,理想情况下只需要检查在当前函数范围内打算使用的参数即可.

As for the additional null checks, one ideally only needs to check the parameters one intends to use within the scope of the current function.

重构代码:

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;
    }
}

这篇关于准备好使用 uint 路由约束了吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 22:23