Как передать объект TimeSpan в метод WCF с использованием JSON - PullRequest
4 голосов
/ 24 августа 2011

Я пытаюсь найти способ вызвать метод WCF с использованием JSON и передать параметр TimeSpan в качестве параметра, но я всегда получаю ответ «Плохой запрос» от службы.

Вот интерфейс службы кода фрагмента:

 [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
    TimeSpan GetTimeSpan(TimeSpan value);

Сервисный звонок:

  String method = "GetTimeSpan";
  String result = null;

  HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + method);
  request.KeepAlive = false;
  request.Method = WebRequestMethods.Http.Post;
  request.ContentType = "application/json";

  JsonSerializer serializer = new JsonSerializer();

  TimeSpan ts = new TimeSpan(23, 59, 59);
  String jsonString = JsonConvert.SerializeObject(ts);


  String data = jsonString;      //jsonString = "23:59:59"
  //I have already tryed with {"value": "23:59:59"} and the result is the same, bad request.
  request.ContentLength = data.Length;

  StreamWriter writer = new StreamWriter(request.GetRequestStream());
  writer.Write(data);
  writer.Close();

  WebResponse response = request.GetResponse();
  StreamReader reader = new StreamReader(response.GetResponseStream());
  result = reader.ReadToEnd();
  response.Close();

Это всего лишь пример. При звонке на сервис без TimeSpan все работает нормально. Мне нужно привести его в порядок, чтобы обеспечить совместимость с другими клиентами, которые обычно используют сервис.

Ответ:

Удаленный сервер возвратил ошибку: (400) Неверный запрос.

Я передаю неверное представление TimeSpan json? Или есть способ определить, как десериализовать TimeSpan, когда служба обрабатывает запрос?

Заранее спасибо

Ответы [ 2 ]

3 голосов
/ 24 августа 2011

Формат для TimeSpan, используемый WCF, отличается от формата, используемого в сериализаторе JSON Newtonsoft (JSON.NET).Вы можете сериализовать один экземпляр TimeSpan, используя DataContractJsonSerializer (DCJS), и это будет формат, требуемый службой REST WCF.

Приведенный ниже код распечатает форматы некоторых значений TimeSpan как сериализованные.JSON.NET и DCJS:

public class StackOverflow_7178839
{
    public static void Test()
    {
        foreach (var ts in new TimeSpan[] { new TimeSpan(23, 59, 59), new TimeSpan(3, 4, 5, 6), new TimeSpan(-4, 3, 4, 5, 333) })
        {
            Console.WriteLine("For TimeSpan value: {0}", ts);
            Console.WriteLine("  {0}", Newtonsoft.Json.JsonConvert.SerializeObject(ts));
            DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(TimeSpan));
            MemoryStream ms = new MemoryStream();
            dcjs.WriteObject(ms, ts);
            Console.WriteLine("  {0}", Encoding.UTF8.GetString(ms.ToArray()));
        }
    }
}
0 голосов
/ 21 февраля 2014

Для тех, у кого все еще есть проблема с сериализатором WCF, я нашел решение, подобное этому: используйте свой собственный форматер, но обязательно очистите все форматеры.

private void RegisterRoute() {
            var config = new WebApiConfiguration() { EnableHelpPage = true, EnableTestClient = true };
            config.Formatters.Clear();
            config.Formatters.Add(new JsonNetMediaTypeFormatter());
            config.MaxReceivedMessageSize = 2097151;
            config.MaxBufferSize = 2097151;
            RouteTable.Routes.SetDefaultHttpConfiguration(config);
            RouteTable.Routes.MapServiceRoute("sys", config);
}
...