将日期时间偏移量作为路由属性传递



我已经查看了有关日期时间偏移查询参数的问题,但我明确希望能够将日期时间偏移量作为路由属性传递,而不是查询参数(可能需要在日期之后进一步路由(。此外,我想要一条不包含日期的路线,如下所示:

[Route("api/Controller/Action/")]
[HttpGet]
public async Task<ActionResult> ControllerAction() 
{
//blah
}
[Route("api/Controller/Action/{dateParam:DateTimeOffset}")]
[HttpGet]
public async Task<ActionResult> ControllerAction(DateTimeOffset dateParam)
{
//blah
}

这些路由都返回一个InvalidOperationException: The constraint reference 'DateTimeOffset' could not be resolved to a type. Register the constraint type with 'Microsoft.AspNetCore.Routing.RouteOptions.ConstraintMap'.

为了尝试解决此问题,我添加并注册了一个约束:

//Constraint
public class DateTimeOffsetConstraint : IRouteConstraint
{
public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values,
RouteDirection routeDirection)
{
if (values.TryGetValue(routeKey, out var value) && value != null)
{
return value is DateTimeOffset;
}
return false;
}
}
//In startup configure services
services.Configure<RouteOptions>(opt => opt.ConstraintMap.Add("DateTimeOffsetConstraint", typeof(DateTimeOffsetConstraint)));
//In controller, altered second route to use constraint
[Route("api/Controller/Action/{dateParam:DateTimeOffsetConstraint}")]
[HttpGet]
public async Task<ActionResult> ControllerAction(DateTimeOffset dateParam)
{
//blah
}

调用该更改后,第一个路由返回InvalidOperationException: Unable to resolve service for type 'System.DateTimeOffset',而第二个带有 DateTimeOffset 的路由(采用正确的祖鲁时间 json 格式,例如 2019-10-02T05:04:18.070Z(返回 404。

以下问题由@Kirk拉金... 控制器采用 IDatePeriodRepository,这是在另一个项目中定义的。这在某一时刻将日期时间偏移量传递到构造函数中

public interface IDatePeriodRepository
{
Task<int> GetDatePeriod();
Task<int> GetDatePeriod(DateTimeOffset date);
}
//Defined in seperate file
internal class DatePeriodRepository: IDatePeriodRepository
{
private readonly DateTimeOffset _dateCycleStart;
public DatePeriodRepository(DateTimeOffset dateCycleStart)
{
_dateCycleStart = dateCycleStart;
}
public Task<int> GetDatePeriod()
{
return GetDatePeriod(DateTimeOffset.Now);
}
public Task<int> GetDatePeriod(DateTimeOffset date)
{
var yearDiff = (date.Year - _billingCycleStart.Year) * 12;
var monthDiff = yearDiff + date.Month - _dateCycleStart.Month;
return Task.FromResult(monthDiff);
}
}

这是使用服务集合扩展构造的

public static class ServiceCollectionExtension
{
public static IServiceCollection AddDatePeriodRepository(this IServiceCollection services, Action<Options> configuration)
{
var options = new Options();
configuration(options);
services.AddSingleton(options);
services.Configure(configuration);
return services.AddScoped<IDatePeriodRepository, DatePeriodRepository>();
}
}
//Used in startup ConfigureServices
services.AddBillingPeriodRepository(opt =>
opt.BillingPeriodCycleStart = Configuration.GetValue<DateTimeOffset>("BillingPeriodCycleStart"));

如何将日期时间偏移量作为路由属性?

Smudge202'a 答案有效,但我还必须像这样更改 constrinat 匹配方法:

public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values,
RouteDirection routeDirection)
{
if (values.TryGetValue(routeKey, out var value) && value != null)
{
return DateTimeOffset.TryParse(value.ToString(), out _);
}
return false;
}

您正在将DateTimeOffset注入DatePeriodRepository,但是您的 DI 设置正在配置Options类。

更改DatePeriodRepository以期望配置的Options类:

internal class DatePeriodRepository: IDatePeriodRepository
{
private readonly DateTimeOffset _dateCycleStart;
public DatePeriodRepository(Options options)
{
_dateCycleStart = options.BillingPeriodCycleStart;
}
public Task<int> GetDatePeriod()
{
return GetDatePeriod(DateTimeOffset.Now);
}
public Task<int> GetDatePeriod(DateTimeOffset date)
{
var yearDiff = (date.Year - _billingCycleStart.Year) * 12;
var monthDiff = yearDiff + date.Month - _dateCycleStart.Month;
return Task.FromResult(monthDiff);
}
}

最新更新