使用newtonsoft json

时间:2015-06-15 23:01:11

标签: json vb.net wcf json.net

我正在尝试创建一个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]'。

请你纠正我错误的地方或我做错了什么。

2 个答案:

答案 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函数解决了很少的其他问题。

谢谢。