如何传递datetime参数?

Nic*_*eon 72 asp.net datetime asp.net-web-api

如何将UTC日期传递给Web API?

传递2010-01-01工作正常,但是当我传递UTC日期(例如2014-12-31T22:00:00.000Z时间组件)时,我得到HTTP 404响应.所以

http://domain/api/controller/action/2012-12-31T22:00:00.000Z
Run Code Online (Sandbox Code Playgroud)

产生404错误响应,而

http://domain/api/controller/action/2012-12-31
Run Code Online (Sandbox Code Playgroud)

工作良好.

那么如何将UTC日期传递给Web API - 或者至少指定日期时间?

Vin*_*els 29

问题是双重的:

1. .路线中

默认情况下,IIS将所有URI中的点作为静态资源处理,尝试返回它并完全跳过进一步处理(通过Web API).这在您的Web.config中的部分中配置system.webServer.handlers:默认处理程序句柄path="*.".你不会找到关于这个path属性中的奇怪语法的文档(正则表达式会更有意义),但这显然意味着"任何不包含点的东西"(以及下面第2点的任何字符).因此名字中的'无扩展' ExtensionlessUrlHandler-Integrated-4.0.

在我看来,按照"正确性"的顺序,可能有多种解决方案:

  • 添加一个专门用于必须允许点的路由的新处理程序.请务必在默认值之前添加它.要执行此操作,请确保先删除默认处理程序,然后将其添加回您的处理程序之后.
  • path="*."属性更改为path="*".然后它会抓住一切.请注意,从那时起,您的web api将不再将带点的来电解释为静态资源!如果您在web api上托管静态资源,那么不建议这样做!
  • 将以下内容添加到Web.config中以无条件地处理所有请求:在<system.webserver>:<modules runAllManagedModulesForAllRequests="true">

2. :路线中

更改上述内容后,默认情况下会出现以下错误:

从客户端(:)检测到潜在危险的Request.Path值.

您可以在Web.config中更改预定义的不允许/无效字符.在<system.web>,添加以下内容:<httpRuntime requestPathInvalidCharacters="&lt;,&gt;,%,&amp;,*,\,?" />.我已经删除了:无效字符的标准列表.

更简单/更安全的解决方案

虽然不是您问题的答案,但更安全,更简单的解决方案是更改请求,以便不需要所有这些.这可以通过两种方式完成:

  1. 将日期作为查询字符串参数传递,如?date=2012-12-31T22:00:00.000Z.
  2. 剥离.000每个请求.你还需要允许:(cfr第2点).


Sim*_*ell 17

我感觉到你的痛苦......还有另一种日期时间格式......正是你所需要的!

使用Web Api 2可以使用路由属性指定参数.

因此,对于您的类和方法的属性,您可以使用此utc格式编写REST URL,但是您遇到了麻烦(显然是ISO8601,可能是使用startDate.toISOString())

[Route(@"daterange/{startDate:regex(^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$)}/{endDate:regex(^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$)}")]
    [HttpGet]
    public IEnumerable<MyRecordType> GetByDateRange(DateTime startDate, DateTime endDate)
Run Code Online (Sandbox Code Playgroud)

....但是,虽然这适用于一个日期(startDate),但由于某种原因,当endDate采用这种格式时它不起作用...调试了几个小时,只有线索是异常说它不喜欢冒号":"(甚至虽然web.config设置为:

<system.web>
    <compilation debug="true" targetFramework="4.5.1" />
    <httpRuntime targetFramework="4.5.1" requestPathInvalidCharacters="" />
</system.web>
Run Code Online (Sandbox Code Playgroud)

因此,让我们制作另一种日期格式(取自ISO日期格式的polyfill)并将其添加到Javascript日期(为简洁起见,最多只转换为几分钟):

if (!Date.prototype.toUTCDateTimeDigits) {
    (function () {

        function pad(number) {
            if (number < 10) {
                return '0' + number;
            }
            return number;
        }

        Date.prototype.toUTCDateTimeDigits = function () {
            return this.getUTCFullYear() +
              pad(this.getUTCMonth() + 1) +
              pad(this.getUTCDate()) +
              'T' +
              pad(this.getUTCHours()) +
              pad(this.getUTCMinutes()) +
              'Z';
        };

    }());
}
Run Code Online (Sandbox Code Playgroud)

然后,当您将日期发送到Web API 2方法时,您可以将它们从字符串转换为日期:

[RoutePrefix("api/myrecordtype")]
public class MyRecordTypeController : ApiController
{


    [Route(@"daterange/{startDateString}/{endDateString}")]
    [HttpGet]
    public IEnumerable<MyRecordType> GetByDateRange([FromUri]string startDateString, [FromUri]string endDateString)
    {
        var startDate = BuildDateTimeFromYAFormat(startDateString);
        var endDate = BuildDateTimeFromYAFormat(endDateString);
    ...
    }

    /// <summary>
    /// Convert a UTC Date String of format yyyyMMddThhmmZ into a Local Date
    /// </summary>
    /// <param name="dateString"></param>
    /// <returns></returns>
    private DateTime BuildDateTimeFromYAFormat(string dateString)
    {
        Regex r = new Regex(@"^\d{4}\d{2}\d{2}T\d{2}\d{2}Z$");
        if (!r.IsMatch(dateString))
        {
            throw new FormatException(
                string.Format("{0} is not the correct format. Should be yyyyMMddThhmmZ", dateString)); 
        }

        DateTime dt = DateTime.ParseExact(dateString, "yyyyMMddThhmmZ", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);

        return dt;
    }
Run Code Online (Sandbox Code Playgroud)

所以网址会是

http://domain/api/myrecordtype/daterange/20140302T0003Z/20140302T1603Z
Run Code Online (Sandbox Code Playgroud)

汉塞尔曼在这里提供了一些相关信息:

http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx


Fre*_*imb 15

在您的Product Web API控制器中:

[RoutePrefix("api/product")]
public class ProductController : ApiController
{
    private readonly IProductRepository _repository;
    public ProductController(IProductRepository repository)
    {
        this._repository = repository;
    }

    [HttpGet, Route("orders")]
    public async Task<IHttpActionResult> GetProductPeriodOrders(string productCode, DateTime dateStart, DateTime dateEnd)
    {
        try
        {
            IList<Order> orders = await _repository.GetPeriodOrdersAsync(productCode, dateStart.ToUniversalTime(), dateEnd.ToUniversalTime());
            return Ok(orders);
        }
        catch(Exception ex)
        {
            return NotFound();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在Fiddler中测试GetProductPeriodOrders方法 - Composer:

http://localhost:46017/api/product/orders?productCode=100&dateStart=2016-12-01T00:00:00&dateEnd=2016-12-31T23:59:59
Run Code Online (Sandbox Code Playgroud)

日期时间格式:

yyyy-MM-ddTHH:mm:ss
Run Code Online (Sandbox Code Playgroud)

javascript传递参数使用moment.js

const dateStart = moment(startDate).format('YYYY-MM-DDTHH:mm:ss');
const dateEnd = moment(endDate).format('YYYY-MM-DDTHH:mm:ss');
Run Code Online (Sandbox Code Playgroud)


Bon*_*lin 11

作为 sk 答案的类似替代方案,我可以Date.prototype.toISOString()在查询字符串中传递格式化为 的日期。这是标准的 ISO 8601 格式,它被 .Net Web API 控制器接受,无需任何额外的路由或操作配置。

例如

var dateString = dateObject.toISOString(); // "2019-07-01T04:00:00.000Z"
Run Code Online (Sandbox Code Playgroud)


Ken*_*max 6

这是可行解决方案的解决方案和模型.在客户端使用Moment.js格式化日期,转换为unix时间.

 $scope.startDate.unix()
Run Code Online (Sandbox Code Playgroud)

将路线参数设置得很长.

[Route("{startDate:long?}")]
public async Task<object[]> Get(long? startDate)
{
    DateTime? sDate = new DateTime();

        if (startDate != null)
        {
            sDate = new DateTime().FromUnixTime(startDate.Value); 
        }
        else
        {
            sDate = null;
        }
         ... your code here!
  }
Run Code Online (Sandbox Code Playgroud)

为Unix时间创建扩展方法.Unix DateTime方法


Nic*_*eon 3

事实上,将参数显式指定为 ?date='fulldatetime' 非常有效。所以这将是现在的一个解决方案:不要使用逗号,而是使用旧的 GET 方法。


归档时间:

查看次数:

120790 次

最近记录:

6 年,7 月 前