我正在尝试创建一个WCF Json Rest并在WPF Phone 8.1 App(不是silverlight)中使用相同的
。我的 WCF 是:
<OperationContract()>
<WebGet(UriTemplate:="getdata", ResponseFormat:=WebMessageFormat.Json)>
Function DoWork() As Dictionary(Of Integer, String)
WCF代码:
Public Class BasicService
Implements IBasicService
Public Function DoWork() As Dictionary(Of Integer, String) Implements IBasicService.DoWork
Dim k As New Dictionary(Of Integer, String)
k.Add(1, "One")
k.Add(2, "Two")
Return k
End Function
End Class
手机消费代码:
Dim httpCli As New System.Net.Http.HttpClient()
Dim httpres As Task(Of HttpResponseMessage) = httpCli.GetAsync("http://localhost:4149/BasicService.svc/getdata")
Dim tk As Task(Of String)
tk = httpres.Result.Content.ReadAsStringAsync
Try
Dim resultstring As String = tk.Result.Substring(tk.Result.IndexOf("{"), tk.Result.LastIndexOf("}") + 1 - tk.Result.IndexOf("{"))
Dim DoWorkResult As Dictionary(Of Integer, String) = Newtonsoft.Json.JsonConvert.DeserializeObject(resultstring)
Catch ex As Exception
End Try
Try
Dim DoWorkResult As Dictionary(Of Integer, String) = Newtonsoft.Json.JsonConvert.DeserializeObject(tk.Result)
Catch ex As Exception
End Try
WCF的小提琴手数据是:.RAW:
HTTP/1.1 200 OK Cache-Control: private Content-Type: application/json; 字符集=utf-8 服务器:Microsoft-IIS/8.0 X-ASPNet版本:4.0.30319 X源文件: =?UTF-8?B?RTpcUmFnaGF2YVxpbXBcUHJvamVjdHNcTUNvbGxlY3RvclxNQ1dDRlxCYXNpY1NlcnZpY2Uuc3ZjXGdldGRhdGE=?= X-供电者: ASP.NET 日期: 星期一, 15 六月 2015 22:50:53 GMT 内容长度:49
[{"键":1,"值":"一"},{"键":2,"值":"二"}]
网页视图:
[{"键":1,"值":"一"},{"键":2,"值":"二"}]
在代码中反序列化时:
第一次尝试使用从"{"到"}"的结果文本进行捕获时出错:其他 读取完 JSON 内容后遇到的文本:,。路径 '',行 1、位置23。
第二次尝试使用未修改的 json 字符串进行捕获时出错:
无法将类型为"Newtonsoft.Json.Linq.JArray"的对象强制转换为类型 'System.Collections.Generic.Dictionary'2[System.Int32,System.String]'.
你能纠正我哪里出错了或我犯了什么错误吗?
您使用的是 Json.NET,但您的 json 字符串表示DataContractJsonSerializer
使用的格式的字典,而不是更简单、更传统的 Json.NET 格式。
解决此问题的一种方法是切换到 DataContractJsonSerializer
,如下所示:VB.net JSON 反序列化。
如果您希望坚持使用 Json.NET,则需要创建自定义JsonConverter
例如:
Public Class KeyValueDictionaryConverter(Of TKey, TValue)
Inherits JsonConverter
Public Overrides Function CanConvert(objectType As Type) As Boolean
Return GetType(IDictionary(Of TKey, TValue)).IsAssignableFrom(objectType)
End Function
Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
Dim array = serializer.Deserialize(Of KeyValuePair(Of TKey, TValue)())(reader)
If array Is Nothing Then
Return existingValue
End If
Dim dict = (If(TryCast(existingValue, IDictionary(Of TKey, TValue)), DirectCast(serializer.ContractResolver.ResolveContract(objectType).DefaultCreator()(), IDictionary(Of TKey, TValue))))
For Each pair As KeyValuePair(Of TKey, TValue) In array
dict.Add(pair.Key, pair.Value)
Next
Return dict
End Function
Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
serializer.Serialize(writer, DirectCast(value, IDictionary(Of TKey, TValue)).Select(Function(p) p))
End Sub
End Class
然后像这样使用它:
Dim json As String = "[{""Key"":1,""Value"":""One""},{""Key"":2,""Value"":""Two""}]"
Dim settings = New JsonSerializerSettings()
settings.Converters.Add(New KeyValueDictionaryConverter(Of Integer, String)())
Dim dict = JsonConvert.DeserializeObject(Of Dictionary(Of Integer, String))(json, settings)
加代码断言所有内容都已读取:
Dim json2 = JsonConvert.SerializeObject(dict, Newtonsoft.Json.Formatting.Indented, settings)
If Not JToken.DeepEquals(JToken.Parse(json), JToken.Parse(json2)) Then
Debug.Assert(JToken.DeepEquals(JToken.Parse(json), JToken.Parse(json2)))
Throw New ApplicationException("Tokens Not Equal")
End If
工作小提琴。
这不是最好的解决方案,但它解决了我对交叉平台的基本需求,因为客户端和服务器代码是由我完成的,我使用 Response 格式作为 XMl,每个函数只返回字符串,但该函数返回 JSON 序列化字符串。
Dim k As New Dictionary(Of Integer, String)
k.Add(1, "One One ~ ! @ # $ % ^ & * ( ) _ + | , . / ; ' [ ] < > ? : "" { } - = / * - + ")
k.Add(2, "Two")
Return Newtonsoft.Json.JsonConvert.SerializeObject(k, Newtonsoft.Json.Formatting.None)
在客户端,我过滤从 { 到 } 的字符串并使用 json.net 反序列化。 :)
Dim resultstring As String = tk.Result.Substring(tk.Result.IndexOf("{"), tk.Result.LastIndexOf("}") + 1 - tk.Result.IndexOf("{"))
resultstring = Net.WebUtility.HtmlDecode(resultstring)
Dim DoWorkResult As Dictionary(Of Integer, String) = Newtonsoft.Json.JsonConvert.DeserializeObject(resultstring, GetType(Dictionary(Of Integer, String)))
我目前面临的错误是解决特殊字符,例如"&"作为"&"发送,以及我使用 HTMLDecode 函数解决的其他一些错误。
谢谢。