将值从 Angular 应用程序发布到 .Net Core WebAPI 时忽略时区
Ignore timezone when posting value from Angular app to .Net Core WebAPI
我正在从我的 Angular
申请中将以下 JSON 发布到 .Net Core WebAPI
:
{CompanyBillingHireRateId: 4, CompanyId: 44, AccountId: null, EquipmentId: 128, EffectiveDate: Sun Dec 29 2019 00:00:00 GMT+0200 (South Africa Standard Time)}
如你所见,EffectiveDate
的值如下:EffectiveDate: Sun Dec 29 2019 00:00:00 GMT+0200 (South Africa Standard Time)
下面是我的 .Net Core 控制器方法:
[HttpPut("billing/hirerates/update")]
public async Task<IActionResult> UpdateNewCompanyBillingHireRateAsync([FromBody] CompanyBillingHireRateViewModel model)
{
try
{
var success = await _companyFacade.UpdateCompanyBillingHireRates_Async(model).ConfigureAwait(false);
if (success)
return Created("", success);
return StatusCode((int)HttpStatusCode.BadRequest);
}
catch (CustomException cEx)
{
await _customExceptionProcess.ProcessCustomException(cEx).ConfigureAwait(false);
return StatusCode(cEx.StatusCode, new { Message = cEx.FriendlyMessage ?? "" });
}
}
在我的 .Net 应用程序中,EffectiveDate
被接收为:{2019/12/28 22:00:00 +00:00}
在我的 Startup.cs
中,我试图将 API 配置为忽略时区,并按原样保留接收到的日期值,并在 .Net 中转换为相应的 datetime
,但没有这样做。这是我的 Startup,cs 配置:
services.AddControllers().AddNewtonsoftJson(setup =>
{
setup.SerializerSettings.ContractResolver = new DefaultContractResolver();
setup.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
setup.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat;
setup.SerializerSettings.DateParseHandling = Newtonsoft.Json.DateParseHandling.None;
setup.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;
});
如何配置 API 以忽略时区,只将 JSON 值作为字符串读取,然后解析为从 Angular UI 收到的相应日期?
您可以使用方法 toISOString()
将您的客户端日期转换为标准 ISO8601 格式。
你的约会对象如下:
new Date().toISOString()
"2020-04-15T12:55:28.344Z"
结尾的 "Z" 是零 UTC 偏移量的区域指示符。
作为一般规则,您应该始终在服务器端使用 UTC 日期,并让客户端处理其时区(除非您有其他特殊要求)。
除非我误解了你的问题,否则将 UTC 中的日期传递给服务器就足够了,而无需更改后端。
已更新
根据评论,我看到了两种可能的情况:
1 - 使用 moment.js 可以为您提供许多方法来解析和验证日期。您可以在客户端将日期解析为 UTC 日期(以下代码段来自 moment.js 文档)。
如果您想在用户当地时间的上下文中使用日期:
moment('2016-01-01T23:35:01');
// "2016-01-01T23:35:01-06:00" - UTC offset as the client
如果您希望将日期作为 UTC 日期进行交互,请使用 moment.utc
:
moment.utc('2016-01-01T23:35:01');
// "2016-01-01T23:35:01+00:00" - Date with a utc offset of +0:00:
如果您必须在其他地方处理日期,moment.js 会很有用,即使它会为您的应用增加一些加班时间。
2 - 您可以在模型上添加一个只读 属性,returns 来自数据 属性 的 ISOString。
// In xxx.model.ts
get isoStringDate() {
modelDateProperty.toISOString();
}
因此您不必更改所有使用模型的部分,而最终只需更改带有附加字符串的服务器的合同 属性。
这是我为我的项目解决这个问题所做的:
由于 Angular 在浏览器中运行,而您的浏览器使用 local time
,因此我更改了 API 以相应地处理此问题,如下所示:
services.AddControllers().AddNewtonsoftJson(setup =>
{
setup.SerializerSettings.ContractResolver = new DefaultContractResolver();
setup.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
setup.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;
});
我正在从我的 Angular
申请中将以下 JSON 发布到 .Net Core WebAPI
:
{CompanyBillingHireRateId: 4, CompanyId: 44, AccountId: null, EquipmentId: 128, EffectiveDate: Sun Dec 29 2019 00:00:00 GMT+0200 (South Africa Standard Time)}
如你所见,EffectiveDate
的值如下:EffectiveDate: Sun Dec 29 2019 00:00:00 GMT+0200 (South Africa Standard Time)
下面是我的 .Net Core 控制器方法:
[HttpPut("billing/hirerates/update")]
public async Task<IActionResult> UpdateNewCompanyBillingHireRateAsync([FromBody] CompanyBillingHireRateViewModel model)
{
try
{
var success = await _companyFacade.UpdateCompanyBillingHireRates_Async(model).ConfigureAwait(false);
if (success)
return Created("", success);
return StatusCode((int)HttpStatusCode.BadRequest);
}
catch (CustomException cEx)
{
await _customExceptionProcess.ProcessCustomException(cEx).ConfigureAwait(false);
return StatusCode(cEx.StatusCode, new { Message = cEx.FriendlyMessage ?? "" });
}
}
在我的 .Net 应用程序中,EffectiveDate
被接收为:{2019/12/28 22:00:00 +00:00}
在我的 Startup.cs
中,我试图将 API 配置为忽略时区,并按原样保留接收到的日期值,并在 .Net 中转换为相应的 datetime
,但没有这样做。这是我的 Startup,cs 配置:
services.AddControllers().AddNewtonsoftJson(setup =>
{
setup.SerializerSettings.ContractResolver = new DefaultContractResolver();
setup.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
setup.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat;
setup.SerializerSettings.DateParseHandling = Newtonsoft.Json.DateParseHandling.None;
setup.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;
});
如何配置 API 以忽略时区,只将 JSON 值作为字符串读取,然后解析为从 Angular UI 收到的相应日期?
您可以使用方法 toISOString()
将您的客户端日期转换为标准 ISO8601 格式。
你的约会对象如下:
new Date().toISOString()
"2020-04-15T12:55:28.344Z"
结尾的 "Z" 是零 UTC 偏移量的区域指示符。 作为一般规则,您应该始终在服务器端使用 UTC 日期,并让客户端处理其时区(除非您有其他特殊要求)。
除非我误解了你的问题,否则将 UTC 中的日期传递给服务器就足够了,而无需更改后端。
已更新
根据评论,我看到了两种可能的情况:
1 - 使用 moment.js 可以为您提供许多方法来解析和验证日期。您可以在客户端将日期解析为 UTC 日期(以下代码段来自 moment.js 文档)。
如果您想在用户当地时间的上下文中使用日期:
moment('2016-01-01T23:35:01');
// "2016-01-01T23:35:01-06:00" - UTC offset as the client
如果您希望将日期作为 UTC 日期进行交互,请使用 moment.utc
:
moment.utc('2016-01-01T23:35:01');
// "2016-01-01T23:35:01+00:00" - Date with a utc offset of +0:00:
如果您必须在其他地方处理日期,moment.js 会很有用,即使它会为您的应用增加一些加班时间。
2 - 您可以在模型上添加一个只读 属性,returns 来自数据 属性 的 ISOString。
// In xxx.model.ts
get isoStringDate() {
modelDateProperty.toISOString();
}
因此您不必更改所有使用模型的部分,而最终只需更改带有附加字符串的服务器的合同 属性。
这是我为我的项目解决这个问题所做的:
由于 Angular 在浏览器中运行,而您的浏览器使用 local time
,因此我更改了 API 以相应地处理此问题,如下所示:
services.AddControllers().AddNewtonsoftJson(setup =>
{
setup.SerializerSettings.ContractResolver = new DefaultContractResolver();
setup.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
setup.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;
});