如何使用JSON将TimeSpan对象传递给WCF方法

时间:2011-08-24 16:18:34

标签: .net wcf json rest timespan

我试图找到一种方法来使用JSON调用WCF方法并将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?

提前致谢

3 个答案:

答案 0 :(得分:3)

WCF使用的TimeSpan格式与Newtonsoft JSON序列化程序(JSON.NET)使用的格式不同。您可以使用DataContractJsonSerializer(DCJS)序列化一个TimeSpan实例,这将是WCF REST服务所需的格式。

以下代码将打印出JSON.NET和DCJS序列化的某些TimeSpan值的格式:

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

答案 1 :(得分:0)

对于仍然遇到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);
}

答案 2 :(得分:0)

您可以如下所述形成json并通过

{“ value”:“ PT19H”} =>传递19小时作为时间跨度值

{“ value”:“ PT19H15”} =>通过19小时,15秒作为时间跨度值

{“ value”:“ 23H59M59S”} =>将23小时59分59秒作为时间跨度值传递