2016-08-22 5 views
2

У меня есть проект Visual Studio (2015), который включает клиентскую часть (Xamarin.Forms PCL) и часть веб-сервиса (WCF Rest). Веб-службы используют edmx для связи с базой данных (SQL Server 2016). JSON используется для обмена данными.Bad Request -Post method - JSON DateTime issue

Я новичок в создании/потреблении услуг 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 (' и end с ') /', как это требуется для 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); 

Что я получаю:

Ложные Метод Bad Request: POST, RequestUri: 'http://localhost:51843/ServiceReservation.svc/создать', Версия: 2,0, Содержание: System.Net.Http.StringContent , Заголовки: {Принять: application/json Content-Type: application/json; кодировка = UTF-8
Content-Length: 407} BadRequest 1.1

Был ошибка десериализации объекта типа BikeSharingService.Reservation. Содержимое DateTime '2016-08-22T00: 00: 00 + 02: 00' не начинается с '/ Date (' и заканчивается ') /' в соответствии с требованиями JSON.

+1

Json не определяет стандартный формат даты, но стоит отметить, что Json.Net (который используется много на веб-облицовочный части .Net framework) поддерживает несколько форматов (и даже настраиваемых), поэтому, если вы можете выбрать стандарт, который работает для всех ваших клиентов, вы можете настроить кодировку Json (en/de), чтобы использовать ее изначально. См. Http://www.newtonsoft.com/json/help/html/datesinjson.htm для получения дополнительной информации – Basic

+1

@Basic Большое вам спасибо. Я использовал следующую информацию на странице, которую вы предложили, и она сработала. Так просто, на самом деле :-) JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }; Строка microsoftJson = JsonConvert.SerializeObject (запись, microsoftDateFormatSettings); – user6742834

ответ

4

[Назначен из комментария]

Json не определяет стандартный формат даты, но стоит отметить, что Json.Net (который используется большинством веб-частей в структуре .Net) поддерживает несколько форматов ts из коробки (и даже пользовательские).

Если вы можете выбрать стандарт, который работает для всех ваших клиентов, вы можете настроить кодировку Json (en/de) в .Net, чтобы использовать ее изначально.

См. 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

Что вы пытаетесь использовать, это Epoch DateTime или Unix DateTime.

Чтобы преобразовать объект DateTime в epat datetime, вы можете создать вспомогательный метод. Это либо миллисекунды, либо секунды с 1/1/1970.

Также, если необходимо, вы можете использовать Noda DateTime вместо .NET, у которого есть метод для преобразования.

Вы можете создать новый класс с типом данных string для DateTime и указать 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)); 
+1

Спасибо, что нашли время ответить. Я фактически использовал JsonConverter, как это было предложено Basic, и это сработало. В любом случае, спасибо, что ответили на мой призыв о помощи. – user6742834