字符串路由约束
String Route Constraint
我有一个 ASP .Net Core 1.1 MVC Web API。如何在控制器操作中使用字符串路由约束?
我有以下两个动作:
/ GET: api/Users/5
[HttpGet("{id:int}")]
[Authorize]
public async Task<IActionResult> GetUser([FromRoute] int id)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
User user = await _context.User.SingleOrDefaultAsync(m => m.UserId == id);
if (user == null)
return NotFound();
return Ok(user);
}
// GET: api/Users/abcde12345
[HttpGet("{nameIdentifier:string}")]
[Authorize]
public async Task<IActionResult> GetUserByNameIdentifier([FromRoute] string nameIdentifier)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
User user = await _context.User.SingleOrDefaultAsync(m => m.NameIdentifier == nameIdentifier);
if (user == null)
return NotFound();
return Ok(user);
}
第一个有效但第二个无效 - .Net 不喜欢 "string" 约束。所以基本上,id 我再次执行 HTTPGET 请求:
它必须执行第一个动作,如果我请求
它必须执行第二个...有什么想法吗?谢谢...
不确定我是否理解正确,但是通过 http 的所有内容都是字符串,asp.net 可以像第一种方法一样将字符串转换为 int,但您不必强制执行该字符串来自您的请求,默认情况下所有数据都将采用字符串格式。
abc412 是一个字符串,12352 也是一个字符串格式,如果要确保只允许使用字母字符,则必须在收到数据后在控制器内部执行该检查。您的方法已经通过您的控制器接收到字符串形式的数据 header
public async Task<IActionResult> GetUserByNameIdentifier([FromRoute] string nameIdentifier)
您需要做什么来检查控制器方法中允许的数据并相应地进行。
您也可以只使用两个单独的 apicalls,按 ID 搜索,按名称搜索
如@Aistis所述,路由数据默认为字符串。这就是没有路由约束将数据类型强制为字符串的原因。如果您想将值限制为特定的字符串值,您正在使用的字符串约束很有用,它不能用于将类型强制为字符串。有几个选项可以实现您想要做的事情。
1.Use 正则表达式路由约束。请注意,您需要根据需要更改正则表达式。
// GET: api/Users/abcde12345
[HttpGet("{nameIdentifier:regex(^[[a-zA-Z]])}")]
[Authorize]
public async Task<IActionResult> GetUserByNameIdentifier([FromRoute] string nameIdentifier)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
User user = await _context.User.SingleOrDefaultAsync(m => m.NameIdentifier == nameIdentifier);
if (user == null)
return NotFound();
return Ok(user);
}
2.You 可以如下实现自己的路由约束,再次更改正则表达式以满足您的需要。
public class NameIdRouteConstraint : RegexRouteConstraint
{
public NameIdRouteConstraint() : base(@"([A-Za-z]{3})([0-9]{3})$")
{
}
}
现在,您可以在 Startup.cs 中映射此自定义路由约束,如下所示
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.Configure<RouteOptions>(options =>
options.ConstraintMap.Add("nameId", typeof(NameIdRouteConstraint )));
}
自定义路由约束 "nameId" 可以使用了,如下所示
// GET: api/Users/abcde12345
[HttpGet("{nameIdentifier:nameId}")]
[Authorize]
public async Task<IActionResult> GetUserByNameIdentifier([FromRoute] string nameIdentifier)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
User user = await _context.User.SingleOrDefaultAsync(m => m.NameIdentifier == nameIdentifier);
if (user == null)
return NotFound();
return Ok(user);
}
我有一个 ASP .Net Core 1.1 MVC Web API。如何在控制器操作中使用字符串路由约束?
我有以下两个动作:
/ GET: api/Users/5
[HttpGet("{id:int}")]
[Authorize]
public async Task<IActionResult> GetUser([FromRoute] int id)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
User user = await _context.User.SingleOrDefaultAsync(m => m.UserId == id);
if (user == null)
return NotFound();
return Ok(user);
}
// GET: api/Users/abcde12345
[HttpGet("{nameIdentifier:string}")]
[Authorize]
public async Task<IActionResult> GetUserByNameIdentifier([FromRoute] string nameIdentifier)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
User user = await _context.User.SingleOrDefaultAsync(m => m.NameIdentifier == nameIdentifier);
if (user == null)
return NotFound();
return Ok(user);
}
第一个有效但第二个无效 - .Net 不喜欢 "string" 约束。所以基本上,id 我再次执行 HTTPGET 请求:
它必须执行第一个动作,如果我请求
它必须执行第二个...有什么想法吗?谢谢...
不确定我是否理解正确,但是通过 http 的所有内容都是字符串,asp.net 可以像第一种方法一样将字符串转换为 int,但您不必强制执行该字符串来自您的请求,默认情况下所有数据都将采用字符串格式。
abc412 是一个字符串,12352 也是一个字符串格式,如果要确保只允许使用字母字符,则必须在收到数据后在控制器内部执行该检查。您的方法已经通过您的控制器接收到字符串形式的数据 header
public async Task<IActionResult> GetUserByNameIdentifier([FromRoute] string nameIdentifier)
您需要做什么来检查控制器方法中允许的数据并相应地进行。
您也可以只使用两个单独的 apicalls,按 ID 搜索,按名称搜索
如@Aistis所述,路由数据默认为字符串。这就是没有路由约束将数据类型强制为字符串的原因。如果您想将值限制为特定的字符串值,您正在使用的字符串约束很有用,它不能用于将类型强制为字符串。有几个选项可以实现您想要做的事情。
1.Use 正则表达式路由约束。请注意,您需要根据需要更改正则表达式。
// GET: api/Users/abcde12345
[HttpGet("{nameIdentifier:regex(^[[a-zA-Z]])}")]
[Authorize]
public async Task<IActionResult> GetUserByNameIdentifier([FromRoute] string nameIdentifier)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
User user = await _context.User.SingleOrDefaultAsync(m => m.NameIdentifier == nameIdentifier);
if (user == null)
return NotFound();
return Ok(user);
}
2.You 可以如下实现自己的路由约束,再次更改正则表达式以满足您的需要。
public class NameIdRouteConstraint : RegexRouteConstraint
{
public NameIdRouteConstraint() : base(@"([A-Za-z]{3})([0-9]{3})$")
{
}
}
现在,您可以在 Startup.cs 中映射此自定义路由约束,如下所示
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.Configure<RouteOptions>(options =>
options.ConstraintMap.Add("nameId", typeof(NameIdRouteConstraint )));
}
自定义路由约束 "nameId" 可以使用了,如下所示
// GET: api/Users/abcde12345
[HttpGet("{nameIdentifier:nameId}")]
[Authorize]
public async Task<IActionResult> GetUserByNameIdentifier([FromRoute] string nameIdentifier)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
User user = await _context.User.SingleOrDefaultAsync(m => m.NameIdentifier == nameIdentifier);
if (user == null)
return NotFound();
return Ok(user);
}