C#ASP.NET WebApi路由模板无法使用uri参数

本文关键字:uri 参数 NET WebApi 路由 C#ASP | 更新日期: 2023-09-27 17:57:51

我有一个带有以下控制器和路由的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未发现错误时才命中路由?

C#ASP.NET WebApi路由模板无法使用uri参数

为什么要重新发明轮子。

ASP.NET Web API 2中的属性路由:路由约束

已经存在CCD_ 1约束。

此外,您还可以将最后一个日期设置为可选日期,这样,如果提供了开始日期,它将使用从日期到当前日期进行筛选。

[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) {
    //...
}

还记得通过过滤器或在操作中进行模型验证。

您可以简单地设置所需的参数(问号表示这些参数是可选的)

[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
    )
{
}