C# 使用HttpGet(…)添加约束在ASP.Net核心中不起作用

C# 使用HttpGet(…)添加约束在ASP.Net核心中不起作用,c#,asp.net-web-api,asp.net-core,.net-core,asp.net-core-routing,C#,Asp.net Web Api,Asp.net Core,.net Core,Asp.net Core Routing,我是ASP.NET核心平台的新手。我正在开发一个示例应用程序,其中汇集了来自服务的一些日常数据。我的API签名如下- [HttpGet("daily/{state}/{year}/{month}/{day}")] public async Task<IActionResult> Daily([FromRoute] string state, [FromRoute] int year, [FromRoute] int month, [FromRoute] int day) {

我是ASP.NET核心平台的新手。我正在开发一个示例应用程序,其中汇集了来自服务的一些日常数据。我的API签名如下-

[HttpGet("daily/{state}/{year}/{month}/{day}")]
public async Task<IActionResult> Daily([FromRoute] string state, [FromRoute] int year, [FromRoute] int month, [FromRoute] int day)
{
    //...
}
若我在路由上添加这些约束,那个么我将得到“未找到页面”错误

如果我不加约束的话,效果很好

更新-见以下VS2017屏幕截图。我正在像
http://localhost:51208/api/daily/mah/2018/08/13
并且ModelState的IsValid仍然返回true。为什么?


找不到是因为被调用的URL很可能与正则表达式约束不匹配

考虑检查正则表达式

简单例子

^[A-Z]{1,3}$
在[a-Z]范围内匹配单个字符1到3次

这意味着它将从
A
匹配到
ZZZ

如果长度必须正好为3个字符,则删除该范围

^[A-Z]{3}$
哪个将匹配
AAA
ZZZ

因此,相应地更新约束

[HttpGet("daily/{state:regex(^[[A-Z]]{{3}}$)}/{year:int}/{month:int}/{day:int}")]
请注意,必须转义正则表达式标记。例如,
\
{
}
[
]
字符需要通过加倍来转义路由参数分隔符字符

关于转义正则表达式的参考

为所需的匹配

GET {host}/daily/ABC/2019/01/20

找不到是因为被调用的URL很可能与正则表达式约束不匹配

考虑检查正则表达式

简单例子

^[A-Z]{1,3}$
在[a-Z]范围内匹配单个字符1到3次

这意味着它将从
A
匹配到
ZZZ

如果长度必须正好为3个字符,则删除该范围

^[A-Z]{3}$
哪个将匹配
AAA
ZZZ

因此,相应地更新约束

[HttpGet("daily/{state:regex(^[[A-Z]]{{3}}$)}/{year:int}/{month:int}/{day:int}")]
请注意,必须转义正则表达式标记。例如,
\
{
}
[
]
字符需要通过加倍来转义路由参数分隔符字符

关于转义正则表达式的参考

为所需的匹配

GET {host}/daily/ABC/2019/01/20

你能做的是以一种更简洁的方式为你的get请求制作一个模型

  public class DailyModel
    {
        [Required]
        [RegularExpression("^[A-Z]{3}$", ErrorMessage ="State should be length of 3 and all in Upper Case")]
        public string State { get; set; }
        public int Year { get; set; }
        public int Month { get; set; }
        public int Day { get; set; }
    }
并将数据注释应用于字段,如上面的代码所示。在控制器上,如果请求无效,可以发送模型状态无效消息

  [Route("api/[controller]")]
    public class TestController : Controller
    {

        [HttpGet("daily/{state}/{year}/{month}/{day}")]
        public async Task<IActionResult> Daily([FromRoute] DailyModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

          ...
        }
    }
[路由(“api/[控制器]”)]
公共类TestController:控制器
{
[HttpGet(“daily/{state}/{year}/{month}/{day}”)]
每日公共异步任务([FromRoute]DailyModel)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
...
}
}

您可以更简洁地为get请求制作一个模型

  public class DailyModel
    {
        [Required]
        [RegularExpression("^[A-Z]{3}$", ErrorMessage ="State should be length of 3 and all in Upper Case")]
        public string State { get; set; }
        public int Year { get; set; }
        public int Month { get; set; }
        public int Day { get; set; }
    }
并将数据注释应用于字段,如上面的代码所示。在控制器上,如果请求无效,可以发送模型状态无效消息

  [Route("api/[controller]")]
    public class TestController : Controller
    {

        [HttpGet("daily/{state}/{year}/{month}/{day}")]
        public async Task<IActionResult> Daily([FromRoute] DailyModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

          ...
        }
    }
[路由(“api/[控制器]”)]
公共类TestController:控制器
{
[HttpGet(“daily/{state}/{year}/{month}/{day}”)]
每日公共异步任务([FromRoute]DailyModel)
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
...
}
}

它不工作了
。这是什么意思?与实际发生的情况相比,期望值是多少?你正在调用哪个URL不起作用?检查你的正则表达式。我认为
regex(A-Z)
只适用于一个字符
它不起作用
。这是什么意思?与实际发生的情况相比,期望值是多少?你正在调用哪个URL不起作用?检查你的正则表达式。我认为
regex(A-Z)
只适用于一个字符谢谢你的回答,但这与-GET{host}/daily/abc/2019/01/20和GET{host}/daily/abc/2019/01/20匹配。我的目的是在这种情况下得到404。是的。你是对的。正则表达式在ReGEX编辑器中尝试显示预期结果,但如果放入URL,则失败。如果约束不按预期工作,那么我会考虑自己验证和更新模型。state@Omkar看一看这个谢谢你的回答,但这符合-GET{host}/daily/abc/2019/01/20和GET{host}/每日/aBC/2019/01/20。我的目的是在这种情况下得到404。是的。你是对的。正则表达式在ReGEX编辑器中尝试显示预期结果,但如果放入URL,则失败。如果约束不按预期工作,那么我会考虑自己验证和更新模型。state@Omkar看看这个谢谢。我只想从路由中获取这些参数。@Omkar是的,您也可以对FromRoute属性执行相同的操作。请参阅我的最新答案。只是你们需要像我的回答那个样介绍一个新的模型。@Omkar你们并没有像我建议的那个样使用模型。您应该具有模型的参数。你不想使用模型吗?用这种方式是更好的做法。谢谢。我只想从路由中获取这些参数。@Omkar是的,您也可以对FromRoute属性执行相同的操作。请参阅我的最新答案。只是你们需要像我的回答那个样介绍一个新的模型。@Omkar你们并没有像我建议的那个样使用模型。您应该具有模型的参数。你不想使用模型吗?采用这种方式是更好的做法。