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
问题是双重的:
.路线中默认情况下,IIS将所有URI中的点作为静态资源处理,尝试返回它并完全跳过进一步处理(通过Web API).这在您的Web.config中的部分中配置system.webServer.handlers:默认处理程序句柄path="*.".你不会找到关于这个path属性中的奇怪语法的文档(正则表达式会更有意义),但这显然意味着"任何不包含点的东西"(以及下面第2点的任何字符).因此名字中的'无扩展' ExtensionlessUrlHandler-Integrated-4.0.
在我看来,按照"正确性"的顺序,可能有多种解决方案:
path="*."属性更改为path="*".然后它会抓住一切.请注意,从那时起,您的web api将不再将带点的来电解释为静态资源!如果您在web api上托管静态资源,那么不建议这样做!<system.webserver>:<modules runAllManagedModulesForAllRequests="true">:路线中更改上述内容后,默认情况下会出现以下错误:
从客户端(:)检测到潜在危险的Request.Path值.
您可以在Web.config中更改预定义的不允许/无效字符.在<system.web>,添加以下内容:<httpRuntime requestPathInvalidCharacters="<,>,%,&,*,\,?" />.我已经删除了:无效字符的标准列表.
虽然不是您问题的答案,但更安全,更简单的解决方案是更改请求,以便不需要所有这些.这可以通过两种方式完成:
?date=2012-12-31T22:00:00.000Z..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)
这是可行解决方案的解决方案和模型.在客户端使用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方法
| 归档时间: |
|
| 查看次数: |
120790 次 |
| 最近记录: |