错误请求-Post方法 - JSON DateTime问题

时间:2016-08-22 16:44:21

标签: json rest wcf xamarin.forms httpclient

我有一个Visual Studio(2015)项目,其中包括客户端部分(Xamarin.Forms PCL)和Web服务部分(WCF Rest)。 Web服务使用edmx与数据库通信(SQL Server 2016)。 JSON用于交换数据。

我是创建/使用WCF Rest服务的新手。我没有使用GET方法的问题,但我遇到了POST方法的问题。

此方法是运行良好的服务的一部分:基于GET的方法没有问题。当我从URL或我的客户端(PCL Xamarin.Forms)测试它时,它运行良好。

POST方法(我的第一次)有点问题。

它应该在SQL Server(2016)的表中创建一条新记录。

当我使用Postman(https://www.getpostman.com/)进行测试时,它已经出现问题:它在表中创建了一条记录,但该对象有两个日期,两个日期被1970-01-01取代。

当我使用我的客户联系网络服务时:我收到'错误请求'。

我找了一个解决方案,发现不是放置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"
 }

现在,我想知道如何将该对象发送到服务器。我的对象如何像上面一样被序列化?

我找不到成功的解决方案。

我继续得到“反序列化BikeSharingService.Reservation类型的对象时出错.DateTime内容'2016-08-22T00:00:00 + 02:00'不以'/ Date('开头)结束')/'根据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);

我得到了什么:

  

错误的错误请求方法:POST,RequestUri:   'http://localhost:51843/ServiceReservation.svc / create',版本:2.0,   内容:System.Net.Http.StringContent,Headers:{Accept:   application / json Content-Type:application / json;字符集= UTF-8
  内容长度:407} BadRequest   1.1

     

反序列化类型对象时出错   BikeSharingService.Reservation。 DateTime内容   '2016-08-22T00:00:00 + 02:00'不以'/ Date('开头)结束   ')/'根据JSON的要求。

2 个答案:

答案 0 :(得分:4)

[通过评论推广]

Json没有定义标准的日期格式,但值得注意的是Json.Net(大多数面向网络的.Net框架部分使用)支持多种格式。盒子(甚至是自定义的)。

如果您可以决定适用于所有客户的标准,您可以在.Net中配置Json(en / de)编码以便在本地使用它。

有关如何指定日期格式处理程序的详细信息和详细信息,请参阅http://newtonsoft.com/json/help/html/datesinjson.htm

[来自链接的示例代码]

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)}
}

答案 1 :(得分:1)

您要使用的是Epoch DateTimeUnix DateTime

要将DateTime对象转换为epoch datetime,您可以创建一个辅助方法。它是从1970年1月1日起的毫秒或秒。

此外,如果需要,您可以使用Noda DateTime而不是具有其中方法的.NET进行转换。

您可以为DateTime创建一个string数据类型的新类,并指定一个Casting。或者您可以编写自定义Serialize方法。

默认情况下,序列化后的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+)\)\//, '$1');
var actualDate = new Date(parseInt(milliseconds));