C# ASP.NET WebApi 路由模板不适用于 uri 参数
C# ASP.NET WebApi route template not working with uri parameters
我有一个具有以下控制器和路由的 ASP.NET WebAPI 应用程序:
WebApiConfig.cs
var constraintResolver = new DefaultInlineConstraintResolver();
constraintResolver.ConstraintMap.Add("validDate", typeof(DateConstraint));
Controller.cs
[HttpGet]
[Route("deleted/{from:validDate?}/{to:validDate?}", Name = "GetDeletedData")]
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(IEnumerable<SimpleClass>), Description = "response")]
public async Task<HttpResponseMessage> Get(
[FromUri]string from = "",
[FromUri]string to = ""
)
{
}
约束
public class DateConstraint : IHttpRouteConstraint
{
public bool Match(
HttpRequestMessage request,
IHttpRoute route,
string parameterName,
IDictionary<string, object> values,
HttpRouteDirection routeDirection
)
{
object value;
if (!values.TryGetValue(parameterName, out value))
return false;
var attribute = new DateAttribute();
return attribute.IsValid(value);
}
}
尽管我传递了以下 url,但上面的路由被命中了,即我没有传入和传出参数,但是控制器被命中并且没有任何反应。
http://localhost:65190/products/deleted?adfear=2016-07-01 03:30:05&adfaewr=2016-07-01 03:30:05
如何确保仅在传递正确参数时才命中路由,否则会抛出 404 未找到错误?
你可以简单的把参数设为必填(问号表示可选)
[HttpGet]
[Route("deleted/{from:validDate}/{to:validDate}", Name = "GetDeletedData")]
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(IEnumerable<SimpleClass>), Description = "response")]
public async Task<HttpResponseMessage> Get(
[FromUri]string from = "",
[FromUri]string to = ""
)
{
}
您必须省略约束上的问号和参数的默认值:
[HttpGet]
[Route("deleted/{from:validDate}/{to:validDate}", Name = "GetDeletedData")]
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(IEnumerable<SimpleClass>), Description = "response")]
public async Task<HttpResponseMessage> Get(
[FromUri]string from,
[FromUri]string to
)
{
}
为什么要重新发明轮子。
Attribute Routing in ASP.NET Web API 2:Route Constraints
已经存在 datetime
约束。
您还可以将最后日期设置为可选,这样如果提供了起始日期,它将使用起始日期到当前日期进行过滤。
[HttpGet]
[Route("deleted/{from:datetime}/{to:datetime?}", Name = "GetDeletedData")]
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(IEnumerable<SimpleClass>), Description = "response")]
public async Task<HttpResponseMessage> Get(DateTime from, DateTime? to = null)
{
//....
}
根据您的意见,您可以做这样的事情
//GET products/deleted
[HttpGet]
[Route("deleted")]
public async Task<HttpResponseMessage> Get() {
//...
}
//GET products/deleted/2016-01-01
//GET products/deleted/2016-01-01/2016-03-31
[HttpGet]
[Route("deleted/{from:datetime}/{to:datetime?}", Name = "GetDeletedData")]
public async Task<HttpResponseMessage> Get(DateTime from, DateTime? to = null) {
//...
}
现在应该可以处理这三种情况
//GET products/deleted
//GET products/deleted/{from}
//GET products/deleted/{from}/{to}
更新
如果两个参数都是模式可选的
//GET products/deleted - including query string will hit this
//GET products/deleted?adfear=2016-07-01 03:30:05&adfaewr=2016-07-01 03:30:05
//GET products/deleted/2016-01-01
//GET products/deleted/2016-01-01/2016-03-31
[HttpGet]
[Route("deleted/{from:datetime?}/{to:datetime?}", Name = "GetDeletedData")]
public async Task<HttpResponseMessage> Get(DateTime? from = null, DateTime? to = null) {
//...
}
更新2
基于对话
您可以创建过滤器模型
public class DateRangeFilter {
public DateTime? from { get; set; }
public DateTime? to { get; set; }
}
你可以在你的行动中使用它。
// GET products/deleted
// GET products/deleted?from=2016-01-01&to=2016-03-31
[HttpGet]
[Route("deleted", Name = "GetDeletedData")]
public async Task<HttpResponseMessage> Get([FromUri]DateRangeFilter filter) {
//...
}
还记得通过过滤器或在操作中进行模型验证。
我有一个具有以下控制器和路由的 ASP.NET WebAPI 应用程序:
WebApiConfig.cs
var constraintResolver = new DefaultInlineConstraintResolver();
constraintResolver.ConstraintMap.Add("validDate", typeof(DateConstraint));
Controller.cs
[HttpGet]
[Route("deleted/{from:validDate?}/{to:validDate?}", Name = "GetDeletedData")]
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(IEnumerable<SimpleClass>), Description = "response")]
public async Task<HttpResponseMessage> Get(
[FromUri]string from = "",
[FromUri]string to = ""
)
{
}
约束
public class DateConstraint : IHttpRouteConstraint
{
public bool Match(
HttpRequestMessage request,
IHttpRoute route,
string parameterName,
IDictionary<string, object> values,
HttpRouteDirection routeDirection
)
{
object value;
if (!values.TryGetValue(parameterName, out value))
return false;
var attribute = new DateAttribute();
return attribute.IsValid(value);
}
}
尽管我传递了以下 url,但上面的路由被命中了,即我没有传入和传出参数,但是控制器被命中并且没有任何反应。
http://localhost:65190/products/deleted?adfear=2016-07-01 03:30:05&adfaewr=2016-07-01 03:30:05
如何确保仅在传递正确参数时才命中路由,否则会抛出 404 未找到错误?
你可以简单的把参数设为必填(问号表示可选)
[HttpGet]
[Route("deleted/{from:validDate}/{to:validDate}", Name = "GetDeletedData")]
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(IEnumerable<SimpleClass>), Description = "response")]
public async Task<HttpResponseMessage> Get(
[FromUri]string from = "",
[FromUri]string to = ""
)
{
}
您必须省略约束上的问号和参数的默认值:
[HttpGet]
[Route("deleted/{from:validDate}/{to:validDate}", Name = "GetDeletedData")]
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(IEnumerable<SimpleClass>), Description = "response")]
public async Task<HttpResponseMessage> Get(
[FromUri]string from,
[FromUri]string to
)
{
}
为什么要重新发明轮子。
Attribute Routing in ASP.NET Web API 2:Route Constraints
已经存在 datetime
约束。
您还可以将最后日期设置为可选,这样如果提供了起始日期,它将使用起始日期到当前日期进行过滤。
[HttpGet]
[Route("deleted/{from:datetime}/{to:datetime?}", Name = "GetDeletedData")]
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(IEnumerable<SimpleClass>), Description = "response")]
public async Task<HttpResponseMessage> Get(DateTime from, DateTime? to = null)
{
//....
}
根据您的意见,您可以做这样的事情
//GET products/deleted
[HttpGet]
[Route("deleted")]
public async Task<HttpResponseMessage> Get() {
//...
}
//GET products/deleted/2016-01-01
//GET products/deleted/2016-01-01/2016-03-31
[HttpGet]
[Route("deleted/{from:datetime}/{to:datetime?}", Name = "GetDeletedData")]
public async Task<HttpResponseMessage> Get(DateTime from, DateTime? to = null) {
//...
}
现在应该可以处理这三种情况
//GET products/deleted
//GET products/deleted/{from}
//GET products/deleted/{from}/{to}
更新
如果两个参数都是模式可选的
//GET products/deleted - including query string will hit this
//GET products/deleted?adfear=2016-07-01 03:30:05&adfaewr=2016-07-01 03:30:05
//GET products/deleted/2016-01-01
//GET products/deleted/2016-01-01/2016-03-31
[HttpGet]
[Route("deleted/{from:datetime?}/{to:datetime?}", Name = "GetDeletedData")]
public async Task<HttpResponseMessage> Get(DateTime? from = null, DateTime? to = null) {
//...
}
更新2
基于对话
您可以创建过滤器模型
public class DateRangeFilter {
public DateTime? from { get; set; }
public DateTime? to { get; set; }
}
你可以在你的行动中使用它。
// GET products/deleted
// GET products/deleted?from=2016-01-01&to=2016-03-31
[HttpGet]
[Route("deleted", Name = "GetDeletedData")]
public async Task<HttpResponseMessage> Get([FromUri]DateRangeFilter filter) {
//...
}
还记得通过过滤器或在操作中进行模型验证。