错误请求 -Post 方法 - JSON 日期时间问题
Bad Request -Post method - JSON DateTime issue
我有一个 Visual Studio (2015) 项目,其中包括客户端部分 (Xamarin.Forms PCL) 和 Web 服务部分 (WCF Rest)。 Web 服务使用 edmx 与数据库通信(SQL Server 2016)。 JSON用于交换数据。
我是 creating/consuming WCF Rest 服务的新手。我使用 GET 方法没有问题,但我遇到了 POST 方法的问题。
此方法是运行良好的服务的一部分:基于 GET 的方法没有问题。当我从 URL 或我的客户 (PCL Xamarin.Forms).
测试它时,它运行良好
POST 方法(我的第一个)有点问题。
它应该在 SQL 服务器 (2016) 的 table 中创建一个新记录。
当我使用 Postman (https://www.getpostman.com/) 对其进行测试时,它已经存在一个问题:它在 table 中创建了一条记录,但是该对象有两个日期并且这两个日期被替换为1970-01-01.
当我使用我的客户端联系网络时 service:I 得到 'Bad Request'.
我找了一个解决方案,发现不是放置Datetime值,而是放置从1970-01-01开始的毫秒数。
我在 Postman 中使用了这个建议,发现新行的创建工作正常。
邮递员请求正文:
{
"Reservation_Utilisateur_Id" : "4",
"Reservation_Velo_Id" : "2",
"Reservation_DateDebut" : "\/Date(1245398693390)\/",
"Reservation_PeriodeDebut" : "matin",
"Reservation_DateFin" :"\/Date(1245398693390)\/",
"Reservation_PeriodeFin" : "matin"
}
现在,我想知道如何将该对象发送到服务器。如何像上面那样序列化我的对象?
我找了解决方案没有成功。
我不断得到 "There was an error deserializing the object of type BikeSharingService.Reservation. DateTime content '2016-08-22T00:00:00+02:00' does not start with '/Date(' and end with ')/' as required for JSON."
有人可以给新手我是一个解释,也许还有一些有效的代码吗?
这是我的代码:
我的合同:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "create",
ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
Reservation create(Reservation reservation);
服务方式:
public Reservation create(Reservation reservation)
{
using (MyEntities bse = new MyEntities())
{
Reservation re = new Reservation
{
Reservation_Utilisateur_Id = reservation.Reservation_Utilisateur_Id,
Reservation_Velo_Id = reservation.Reservation_Velo_Id,
Reservation_DateDebut = reservation.Reservation_DateDebut,
Reservation_PeriodeDebut = reservation.Reservation_PeriodeDebut,
Reservation_DateFin = reservation.Reservation_DateFin,
Reservation_PeriodeFin = reservation.Reservation_PeriodeFin,
Reservation_DemandeRecupDomCli = reservation.Reservation_DemandeRecupDomCli
};
bse.Reservations.Add(re);
bse.SaveChanges();
return re;
}
}
在客户端:
const string Url1 = "http://localhost:51843/ServiceReservation.svc/create";
public async Task<Reservation> create(Reservation reservation)
{
string json = JsonConvert.SerializeObject(reservation);
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");
var response = await client.PostAsync(Url1,
new StringContent(
json,
Encoding.UTF8, "application/json"));
return JsonConvert.DeserializeObject<Reservation>(
await response.Content.ReadAsStringAsync());
}
然后在客户端调用方法:
Reservation re =new Reservation();
re.Reservation_Utilisateur_Id = 4;
re.Reservation_Velo_Id = 2;
re.Reservation_DateDebut = DateTime.Now.Date;
re.Reservation_PeriodeDebut = "matin";
re.Reservation_DateFin = DateTime.Now.Date;
re.Reservation_PeriodeFin = "matin";
re.Reservation_DemandeRecupDomCli = 1;
Reservation resultat = await reManager.create(re);
我得到的:
False Bad Request Method: POST, RequestUri:
'http://localhost:51843/ServiceReservation.svc /create', Version: 2.0,
Content: System.Net.Http.StringContent, Headers: { Accept:
application/json Content-Type: application/json; charset=utf-8
Content-Length: 407 } BadRequest
1.1
There was an error deserializing the object of type
BikeSharingService.Reservation. DateTime content
'2016-08-22T00:00:00+02:00' does not start with '/Date(' and end with
')/' as required for JSON.
您尝试使用的是 Epoch DateTime or Unix DateTime。
要将 DateTime 对象转换为纪元日期时间,您可以创建一个辅助方法。它是从 1/1/1970 开始的毫秒数或秒数。
此外,如果需要,您可以使用 Noda DateTime 而不是其中包含转换方法的 .NET。
您可以为 DateTime 创建一个 class 数据类型为 string
的新 class 并指定一个转换。或者您可以编写自定义序列化方法。
默认情况下,序列化后的 DateTime 格式为 ISO 8601 Format。
转换为 Unix 或 Epoch 日期时间的代码:
private static readonly DateTime EpochDateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static long ConvertDateTimeToUnixTime(DateTime date, bool isDatarequiredInMilliSeconds = false, DateTimeKind dateTimeKind = DateTimeKind.Local)
{
return Convert.ToInt64((DateTime.SpecifyKind(date.Value, dateTimeKind).ToUniversalTime() - EpochDateTime).TotalSeconds) * (isDatarequiredInMilliSeconds ? 1000 : 1);
}
如果需要转换回来可以使用下面的方法(source):
var milliseconds = "/Date(1245398693390)/".replace(/\/Date\((-?\d+)\)\//, '');
var actualDate = new Date(parseInt(milliseconds));
[从评论中提升]
Json 没有定义标准的日期格式,但值得注意的是 Json.Net(.Net 框架的大多数面向 Web 的部分都使用它)支持多种格式开箱即用(甚至是定制的)。
如果您可以决定适用于所有客户端的标准,则可以在 .Net 中配置 Json (en/de) 编码以在本机使用它。
有关如何指定日期格式处理程序的更多信息和详细信息,请参阅 http://newtonsoft.com/json/help/html/datesinjson.htm。
[示例代码来自 link]
public void WriteJsonDates()
{
LogEntry entry = new LogEntry
{
LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc),
Details = "Application started."
};
// default as of Json.NET 4.5
string isoJson = JsonConvert.SerializeObject(entry);
// {"Details":"Application started.","LogDate":"2009-02-15T00:00:00Z"}
JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
};
string microsoftJson = JsonConvert.SerializeObject(entry, microsoftDateFormatSettings);
// {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"}
string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter());
// {"Details":"Application started.","LogDate":new Date(1234656000000)}
}
我有一个 Visual Studio (2015) 项目,其中包括客户端部分 (Xamarin.Forms PCL) 和 Web 服务部分 (WCF Rest)。 Web 服务使用 edmx 与数据库通信(SQL Server 2016)。 JSON用于交换数据。
我是 creating/consuming WCF Rest 服务的新手。我使用 GET 方法没有问题,但我遇到了 POST 方法的问题。
此方法是运行良好的服务的一部分:基于 GET 的方法没有问题。当我从 URL 或我的客户 (PCL Xamarin.Forms).
测试它时,它运行良好POST 方法(我的第一个)有点问题。
它应该在 SQL 服务器 (2016) 的 table 中创建一个新记录。
当我使用 Postman (https://www.getpostman.com/) 对其进行测试时,它已经存在一个问题:它在 table 中创建了一条记录,但是该对象有两个日期并且这两个日期被替换为1970-01-01.
当我使用我的客户端联系网络时 service:I 得到 'Bad Request'.
我找了一个解决方案,发现不是放置Datetime值,而是放置从1970-01-01开始的毫秒数。
我在 Postman 中使用了这个建议,发现新行的创建工作正常。
邮递员请求正文:
{
"Reservation_Utilisateur_Id" : "4",
"Reservation_Velo_Id" : "2",
"Reservation_DateDebut" : "\/Date(1245398693390)\/",
"Reservation_PeriodeDebut" : "matin",
"Reservation_DateFin" :"\/Date(1245398693390)\/",
"Reservation_PeriodeFin" : "matin"
}
现在,我想知道如何将该对象发送到服务器。如何像上面那样序列化我的对象?
我找了解决方案没有成功。
我不断得到 "There was an error deserializing the object of type BikeSharingService.Reservation. DateTime content '2016-08-22T00:00:00+02:00' does not start with '/Date(' and end with ')/' as required for JSON."
有人可以给新手我是一个解释,也许还有一些有效的代码吗?
这是我的代码:
我的合同:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "create",
ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
Reservation create(Reservation reservation);
服务方式:
public Reservation create(Reservation reservation)
{
using (MyEntities bse = new MyEntities())
{
Reservation re = new Reservation
{
Reservation_Utilisateur_Id = reservation.Reservation_Utilisateur_Id,
Reservation_Velo_Id = reservation.Reservation_Velo_Id,
Reservation_DateDebut = reservation.Reservation_DateDebut,
Reservation_PeriodeDebut = reservation.Reservation_PeriodeDebut,
Reservation_DateFin = reservation.Reservation_DateFin,
Reservation_PeriodeFin = reservation.Reservation_PeriodeFin,
Reservation_DemandeRecupDomCli = reservation.Reservation_DemandeRecupDomCli
};
bse.Reservations.Add(re);
bse.SaveChanges();
return re;
}
}
在客户端:
const string Url1 = "http://localhost:51843/ServiceReservation.svc/create";
public async Task<Reservation> create(Reservation reservation)
{
string json = JsonConvert.SerializeObject(reservation);
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");
var response = await client.PostAsync(Url1,
new StringContent(
json,
Encoding.UTF8, "application/json"));
return JsonConvert.DeserializeObject<Reservation>(
await response.Content.ReadAsStringAsync());
}
然后在客户端调用方法:
Reservation re =new Reservation();
re.Reservation_Utilisateur_Id = 4;
re.Reservation_Velo_Id = 2;
re.Reservation_DateDebut = DateTime.Now.Date;
re.Reservation_PeriodeDebut = "matin";
re.Reservation_DateFin = DateTime.Now.Date;
re.Reservation_PeriodeFin = "matin";
re.Reservation_DemandeRecupDomCli = 1;
Reservation resultat = await reManager.create(re);
我得到的:
False Bad Request Method: POST, RequestUri: 'http://localhost:51843/ServiceReservation.svc /create', Version: 2.0, Content: System.Net.Http.StringContent, Headers: { Accept: application/json Content-Type: application/json; charset=utf-8
Content-Length: 407 } BadRequest 1.1There was an error deserializing the object of type BikeSharingService.Reservation. DateTime content '2016-08-22T00:00:00+02:00' does not start with '/Date(' and end with ')/' as required for JSON.
您尝试使用的是 Epoch DateTime or Unix DateTime。
要将 DateTime 对象转换为纪元日期时间,您可以创建一个辅助方法。它是从 1/1/1970 开始的毫秒数或秒数。
此外,如果需要,您可以使用 Noda DateTime 而不是其中包含转换方法的 .NET。
您可以为 DateTime 创建一个 class 数据类型为 string
的新 class 并指定一个转换。或者您可以编写自定义序列化方法。
默认情况下,序列化后的 DateTime 格式为 ISO 8601 Format。
转换为 Unix 或 Epoch 日期时间的代码:
private static readonly DateTime EpochDateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static long ConvertDateTimeToUnixTime(DateTime date, bool isDatarequiredInMilliSeconds = false, DateTimeKind dateTimeKind = DateTimeKind.Local)
{
return Convert.ToInt64((DateTime.SpecifyKind(date.Value, dateTimeKind).ToUniversalTime() - EpochDateTime).TotalSeconds) * (isDatarequiredInMilliSeconds ? 1000 : 1);
}
如果需要转换回来可以使用下面的方法(source):
var milliseconds = "/Date(1245398693390)/".replace(/\/Date\((-?\d+)\)\//, '');
var actualDate = new Date(parseInt(milliseconds));
[从评论中提升]
Json 没有定义标准的日期格式,但值得注意的是 Json.Net(.Net 框架的大多数面向 Web 的部分都使用它)支持多种格式开箱即用(甚至是定制的)。
如果您可以决定适用于所有客户端的标准,则可以在 .Net 中配置 Json (en/de) 编码以在本机使用它。
有关如何指定日期格式处理程序的更多信息和详细信息,请参阅 http://newtonsoft.com/json/help/html/datesinjson.htm。
[示例代码来自 link]
public void WriteJsonDates()
{
LogEntry entry = new LogEntry
{
LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc),
Details = "Application started."
};
// default as of Json.NET 4.5
string isoJson = JsonConvert.SerializeObject(entry);
// {"Details":"Application started.","LogDate":"2009-02-15T00:00:00Z"}
JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
};
string microsoftJson = JsonConvert.SerializeObject(entry, microsoftDateFormatSettings);
// {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"}
string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter());
// {"Details":"Application started.","LogDate":new Date(1234656000000)}
}