【问题标题】:How to pass a TimeSpan object to a WCF method using JSON如何使用 JSON 将 TimeSpan 对象传递给 WCF 方法
【发布时间】:2011-08-24 16:18:34
【问题描述】:

我正在尝试找到一种使用 JSON 调用 WCF 方法并将 TimeSpan 作为参数传递的方法,但我总是收到来自服务的“错误请求”响应。

这里是一个sn-p代码服务接口:

 [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) Bad Request。

我是否传递了错误的 TimeSpan json 表示?或者有没有办法定义在服务处理请求时如何反序列化 TimeSpan?

提前致谢

【问题讨论】:

  • TimeSpan 无法序列化。 stackoverflow.com/questions/3232701/…的可能重复
  • @dennis - 这个问题是关于 .NET 3.5 上的 WCF(使用 VS2008 是一个相当好的假设)。也许自 .NET 4.0 以来这已经改变了?也许 OP 可以澄清 .NET 版本?

标签: .net wcf json rest timespan


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    对于仍然对 WCF 序列化程序有问题的任何人,我找到了这样的解决方案:使用您自己的格式化程序,但确保清除所有格式化程序。

    私人无效注册路由(){ 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); }

    【讨论】:

      【解决方案3】:

      你可以按照下面所说的形成json并通过

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

      {"value":"PT19H15"} => 将 19 小时 15 秒作为时间跨度值

      {"value":"23H59M59S"} => 将 23 小时、59 分钟和 59 秒作为时间跨度值

      【讨论】:

        猜你喜欢
        • 2012-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-25
        • 1970-01-01
        • 1970-01-01
        • 2017-07-29
        相关资源
        最近更新 更多