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

发布于 2024-12-01 11:32:46 字数 1434 浏览 1 评论 0原文

我试图找到一种使用 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?

提前致谢

I'm trying to find a way to call a WCF method using JSON and pass a TimeSpan as parameter but I always receive a "Bad request" response from the service.

Here is a snippet code service interface:

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

Service call:

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

This is just an example. When calling a service without TimeSpan everything works fine. I need to put it work in order do keep compatibility with other clients that are consuming the service in the typical way.

Response:

The remote server returned an error: (400) Bad Request.

Am I passing the wrong TimeSpan json representation? Or is there a way to define how to deserialize the TimeSpan when the service handles the request?

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

玩物 2024-12-08 11:32:46

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

The format for TimeSpan used by WCF is not the same one used by the Newtonsoft JSON serializer (JSON.NET) . You can serialize one TimeSpan instance using the DataContractJsonSerializer (DCJS), and that will be the format required by a WCF REST service.

The code below will print out the formats of some TimeSpan values as serialized by both JSON.NET and 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()));
        }
    }
}
此岸叶落 2024-12-08 11:32:46

您可以如下所述形成 json 并传递

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

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

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

You can form the json as mentioned below and pass

{"value":"PT19H"} => Passing 19 Hrs as timespan value

{"value":"PT19H15"} => Passing 19 Hrs, 15 Secs as timespan value

{"value":"23H59M59S"} => Passing 23 Hrs, 59 Mins and 59 Secs as timespan value

樱桃奶球 2024-12-08 11:32:46

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

For anyone who still have a problem with WCF serializer, I have found the solution like this : use your own formatter but make sure clearing all formatter.

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文