2015-06-15 3 views
1

Я пытаюсь создать WCF Json Rest и потреблять то же самое в приложении WPF Phone 8.1 (не silverlight).Ошибка десериализации результата WCF Json с помощью newtonsoft json

Мои 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 

Скрипач данных для ФОС: RAW:

HTTP/1.1 200 OK Cache-Control: private Content-Type: application/json; кодировка = UTF-8 Сервер: Microsoft-IIS/8.0 X-Сеть САШ-версия: 4.0.30319 X-исходников,:?? = UTF-8 В RTpcUmFnaGF2YVxpbXBcUHJvamVjdHNcTUNvbGxlY3RvclxNQ1dDRlxCYXNpY1NlcnZpY2Uuc3ZjXGdldGRhdGE = X-Powered-By: ASP.NET Дата: Пн, 15 июня 2015 г. 22:50:53 GMT Контент-длина: 49

[{«Ключ»: 1, «Значение»: «Один»}, {«Ключ»: 2, «Значение», : "Два"}]

WebView:

[{ "Ключ": 1, "Значение": "Одна"}, { "Ключ": 2, "Ва LUE ":" Два "}]

При десериализации в коде:

Ошибки при первой попытке поймать с результатом текстом из '{' на '}': Дополнительный текста, встречающиеся после дочитал JSON содержание:,. Путь '', линия 1, позиция 23.

Ошибка при второй попытке поймать с не модифицированной строки JSON:

Невозможно привести объект типа 'Newtonsoft.Json.Linq.JArray' в type 'System.Collections.Generic.Dictionary`2 [System.Int32, System.String]'.

Не могли бы вы исправить меня, где я поступил не так, и какую ошибку я сделал.

ответ

0

Это не лучшее решение, но оно решает мою основную потребность в cross plaftform, так как клиентские и серверные коды выполняются мной, я использовал формат Response как XMl, и каждая функция возвращает только строку, но функция возвращает строку JSON serialized ,

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} и deserialise с помощью 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.

спасибо.

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) 

Plus код утверждать, что все было прочитать:

 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 

Working fiddle ,

+0

Я довольно пустой прямо сейчас, Он кажется слишком большим, но правильным, но ищет простое решение, пытался использовать messageformat как xml и отправлять серию json.net serialized, и в нее вошли специальные charecters для пробелов: (Нужно найти пример, чтобы заменить серийный сериализатор по умолчанию в vb (я всегда получаю для C#). – surpavan

+0

Нашел простой способ, но не грязный, но небольшой способ взлома для моей потребности. Ниже мой ответ. времени и обмена знаниями. – surpavan

Смежные вопросы