【问题标题】:Date value changes when sent from angular and received in ASP.NET server从 Angular 发送并在 ASP.NET 服务器中接收时,日期值会发生变化
【发布时间】:2019-02-17 17:40:39
【问题描述】:

我正在将一个包含两个日期的对象从 Angular 6 发送到 ASP.NET Core Web API 方法。 Angular 端的日期是正确的,但是当在 Web API 方法中接收到它们时,它们比从 Angular 应用程序发送的日期晚了一天。

startSprint(id: number, SprintDates: any): Observable<any> {
    this.sprintId = id.toString();
    return this.http.patch<any>(this.baseUrl + 'setSprintDates/' + this.sprintId,
                                SprintDates);
}

上述方法将日期对象发送到 Web API 方法。下面的方法是接收该对象的 Web API 方法,但是当我调试并将光标悬停在 sprintDatesDto 对象上时,收到的值比从 Angular 发送时的值晚一天。

[HttpPatch("setSprintDates/{sprintId}")]
public async Task<IActionResult> SetSprintDates(string sprintId, SprintDatesDto sprintDatesDto)
{
    // Business login related code
    return StatusCode(200);
}

这是SprintDatesDto 类:

namespace AgileFootPrints.API.Dtos
{
    public class SprintDatesDto
    {
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }
    }
}

这是我在 angular Typescript 文件中创建的对象:

sprinDates = {
startDate: Date,
endDate: Date
  };

然后,在 Html 文件中,我使用 ngModel 绑定到 sprintDates 对象属性:

<div class="row">
  <div class="col-md-7 w-100 ">
<mat-form-field class="example-full-width">
  <input
    matInput
    [(ngModel)]="sprinDates.startDate"
    [min]="minDate"
    [max]="maxDate"
    [matDatepicker]="startsAt"
    placeholder="Starts At"
  />
  <mat-datepicker-toggle matSuffix [for]="startsAt"></mat-datepicker-toggle>
  <mat-datepicker #startsAt></mat-datepicker>
</mat-form-field>
  </div>
  <br />
</div>
<div class="row">
  <div class="col-md-7 w-100">
<mat-form-field class="example-full-width">
  <input
    [disabled]="sprinDates.startDate === undefined"
    matInput
    [(ngModel)]="sprinDates.endDate"
    [min]="sprinDates.startDate"
    [max]="maxDate"
    [matDatepicker]="endsAt"
    placeholder="Ends At"
  />
  <mat-datepicker-toggle matSuffix [for]="endsAt"></mat-datepicker-toggle>
  <mat-datepicker #endsAt></mat-datepicker>
</mat-form-field>
  </div>
</div>

【问题讨论】:

  • 分享代码你如何在客户端设置SprintDates
  • 我刚刚用客户端代码更新了帖子,请查看

标签: c# angular asp.net-web-api asp.net-core


【解决方案1】:

一个可能的罪魁祸首是客户端和服务器之间的时区偏移。

当通过 Angular HTTP 客户端发送 JavaScript 日期时,使用 JSON.stingify() 方法将数据转换为 JSON 字符串。当日期转换为这个字符串时,数值时间值实际上被修改为反映没有时区偏移,而不是客户端的时区偏移。这是为了规范实际时间,以防服务器处于不同的时区。

要解决此问题,您需要将日期时间转换为服务器可以解释的字符串格式。为此,有两种方法。您可以从角度使用 DatePipe,也可以使用可用的 Date 函数简单地将日期转换为字符串。

import { DatePipe } from '@angular/common';

在构造函数中:

private datePipe: DatePipe

转换为您需要的任何日期时间格式。

this.sprinDates.StartDate = this.datePipe.transform(this.sprinDates.StartDate, 'MM/dd/yyyy');

我提到的另一种方法是使用日期函数进行转换。

this.sprinDates.StartDate = this.sprinDates.StartDate ? this.sprinDates.StartDate.toLocaleString() : null;

【讨论】:

    【解决方案2】:

    问题在于 Json 解析您的日期的方式,默认情况下,它将添加与 UTC 相比的本地时间(例如:如果您在午夜是 Gmt+1,它将转换为昨天 UTC 的晚上 11 点) ,您需要做的是创建一个文件,该文件将覆盖 MomentDateAdapter 以忽略此转换并在 UTC 中创建所选时间,如下所示:

    import { Inject, Injectable, Optional } from '@angular/core';
    import { MAT_DATE_LOCALE } from '@angular/material';
    import { MomentDateAdapter } from '@angular/material-moment-adapter';
    import { Moment } from 'moment';
    import * as moment from 'moment';
    
    @Injectable()
    export class MomentUtcDateAdapter extends MomentDateAdapter {
      constructor(@Optional() @Inject(MAT_DATE_LOCALE) dateLocale: string) {
        super(dateLocale);
      }
    
      createDate(year: number, month: number, date: number): Moment {
        // Moment.js will create an invalid date if any of the components are out of bounds, but we
        // explicitly check each case so we can throw more descriptive errors.
        if (month < 0 || month > 11) {
          throw Error(
            `Invalid month index "${month}". Month index has to be between 0 and 11.`
          );
        }
    
        if (date < 1) {
          throw Error(`Invalid date "${date}". Date has to be greater than 0.`);
        }
    
        const result = moment.utc({ year, month, date }).locale(this.locale);
    
        // If the result isn't valid, the date must have been out of bounds for this month.
        if (!result.isValid()) {
          throw Error(`Invalid date "${date}" for month with index "${month}".`);
        }
    
        return result;
      }
    }
    

    接下来只需将以下提供程序和这个新文件导入到您的 app.module 或 angular material 模块(如果有的话)

    @NgModule({
      providers: [
        { provide: MAT_DATE_LOCALE, useValue: 'en-GB' },
          { provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS },
          { provide: DateAdapter, useClass: MomentUtcDateAdapter },
      ],
      imports: [
       MomentUtcDateAdapter,
       ... rest of your imports]
    

    【讨论】:

      猜你喜欢
      • 2021-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多