我正在尝试创建一个WCF Json Rest并在WPF Phone 8.1应用程序(不是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的Fiddler数据是: RAW:
HTTP / 1.1 200 OK Cache-Control:private Content-Type:application / json; charset = utf-8服务器:Microsoft-IIS / 8.0 X-AspNet-版本:4.0.30319 X-SourceFiles: =?UTF-8 2 B 4 RTpcUmFnaGF2YVxpbXBcUHJvamVjdHNcTUNvbGxlY3RvclxNQ1dDRlxCYXNpY1NlcnZpY2Uuc3ZjXGdldGRhdGE =?= X-Powered-By:ASP.NET日期:星期一,2015年6月15日22:50:53 GMT 内容长度:49
[{ “密钥”:1, “值”: “一”},{ “键”:2 “值”: “两个”}]
web视图:
[{ “密钥”:1, “值”: “一”},{ “键”:2 “值”: “两个”}]
在代码中进行反序列化时:
首先尝试使用“{”到“}”的结果文本尝试捕获:其他 完成阅读JSON内容后遇到的文本:,。路径'',行 1,位置23。
第二次尝试使用未修改的json字符串捕获错误:
无法将“Newtonsoft.Json.Linq.JArray”类型的对象强制转换为类型 'System.Collections.Generic.Dictionary`2 [System.Int32,System.String]'。
请你纠正我错误的地方或我做错了什么。
答案 0 :(得分:1)
您正在使用Json.NET,但您的json字符串表示DataContractJsonSerializer
使用的格式的字典,而不是更简单和更传统的Json.NET format。
解决此问题的一种方法是切换到DataContractJsonSerializer
,如下所示:VB.net JSON Deserialize。
如果您更喜欢坚持使用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
工作fiddle。
答案 1 :(得分:0)
这不是最好的解决方案,但它解决了我对cross plaftform的基本需求,因为客户端和服务器代码由我完成,我使用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)
在客户端,我从{to}过滤掉字符串,并用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)))
我目前面临的错误是解决像'&amp;'这样的特殊字符。被发送为“&amp; amp;”我使用HTMLDecode函数解决了很少的其他问题。
谢谢。