WCF Json 结果反序列化错误与牛顿软件 json



我正在尝试创建一个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 函数解决的其他一些错误。

谢谢。

最新更新