2011-11-18 68 views
0

我有一个返回JSON的Web服务。在测试程序时,无论是通过浏览器还是测试程序,该字符串总是会添加额外的反斜杠。例如,如果我期待我的输出看起来像:WCF Web服务返回JSON字符串和额外的后挡格

{"ack":{"qry":[{"retn":"abcd","desc":"defg"}] 

它实际上是显示为

{\"ack\":{\"qry\":[{\"retn\":\"abcd\",\"desc\":\defg\"}. 

我使用JSON.NET和JsonTextWriter创建的字符串。

private string jsonParse(string respStr) 
    { 
     string jSonStr; 
     StringBuilder sb = new StringBuilder(); 
     StringWriter sw = new StringWriter(sb); 

     JsonWriter writer = new JsonTextWriter(sw); 
     writer.Formatting = Formatting.None; 

     List<string> commands = (from word in respStr.Split(':') select word).ToList(); 
     for (int j = 0; j < commands.Count; j += 3) 
     { 
      List<string> param = (from par in commands[j + 2].Split(new Char[] { ',', '=' }) select par).ToList(); 

      writer.WriteStartObject(); 
      writer.WritePropertyName(commands[j]); 
      writer.WriteStartObject(); 
      writer.WritePropertyName(commands[j + 1]); 
      writer.WriteStartArray(); 
      writer.WriteStartObject(); 
      for (int i = 0; i < param.Count - 1; i += 2) 
      { 
       writer.WritePropertyName(param[i]); 
       writer.WriteValue(param[i + 1]); 
      } 
      writer.WriteEndObject(); 

      writer.WriteEndArray(); 
      writer.WriteEndObject(); 
      writer.WriteEndObject(); 
     } 
     jSonStr = sb.ToString(); 

     return jSonStr; 
    } 

我的Web服务操作合约看起来是这样的:

[OperationContract] 
[WebGet(ResponseFormat=WebMessageFormat.Json, UriTemplate="/{system}/{command}")] 
string getMethod(string system, string command); 

最后我使用的测试程序使用HttpWebRequest的,像这样:

HttpWebRequest GETRequest = (HttpWebRequest)WebRequest.Create(url); 
GETRequest.Method = "GET"; 

Console.WriteLine("Sending GET Request"); 
HttpWebResponse GETResponse = (HttpWebResponse)GETRequest.GetResponse(); 
Stream GETResponseStream = GETResponse.GetResponseStream(); 
StreamReader sr = new StreamReader(GETResponseStream); 

Console.WriteLine(sr.ReadToEnd()); 

任何线索为什么会发生这种情况?

回答

3

不知道为什么会发生这种情况(可能会将字符串重复编码为JSON字符串),但我可以建议您最好不要使用JSON .Net来代替使用DataContracts - 它更简单并且意味着您的服务不需要知道它正在运行的基础架构。如果你定义方法如下所示:

[OperationContract] 
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/{system}/{command}")] 
Response getMethod(string system, string command); 

然后做这样的事情了Response对象:

[DataContract] 
public class Response 
{ 
    [DataMember(Name = "ack")] 
    public Acknoweldge Acknowledge { get; set; } 
} 

[DataContract] 
public class Acknoweldge 
{ 
    [DataMember(Name = "qry")] 
    public IEnumerable<Query> Query { get; set; } 
} 

[DataContract] 
public class Query 
{ 
    [DataMember(Name = "desc")] 
    public string Description { get; set; } 

    [DataMember(Name = "retn")] 
    public string Return { get; set; } 
} 

然后实现你的方法,像这样(我只返回一个虚拟对象):

public Response getMethod(string system, string command) 
{ 
    return new Response 
     { 
      Acknowledge = new Acknoweldge 
       { 
        Query = new List<Query> 
         { 
          new Query { Return = "abcd", Description = "defg" } 
         } 
       } 
     }; 
} 

运行客户端代码示例,你会得到你正在寻找的结果,具体为:

{"ack":{"qry":[{"desc":"defg","retn":"abcd"}]}} 
+0

我喜欢这个解决方案。您的服务应该完全不知道客户如何使用其数据。除非绝对必要,否则绝不要为特定客户编写服务。 –