问题
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
回答1:
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()));
}
}
}
回答2:
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); }
来源:https://stackoverflow.com/questions/7178839/how-to-pass-a-timespan-object-to-a-wcf-method-using-json