liuhaipeng905 / servicestack

Automatically exported from code.google.com/p/servicestack
0 stars 1 forks source link

JSON deserialization Issue on MonoTouch / iPhone Simulator #3

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Here are some basic steps to reproduce the issue

1. Create a service on a Windows Machine (Mine was Windows Server 2008)
2. Create an iphone client in MonoTouch which consumes the service at it's JSON 
endpoint (using 
ServiceStack.Client.dll)

The expected output is a correct deserialization of the object. What I get 
instead is:

Unhandled Exception: System.Runtime.Serialization.SerializationException: 
JsonDataContractDeserializer: Error converting to type: Deserialization has 
failed ---> 
System.Runtime.Serialization.SerializationException: Deserialization has failed 
---> 
System.Xml.XmlException: Comma is required unless an array or object is at the 
end (1,52)
  at System.Runtime.Serialization.Json.JsonReader.ReadContent (Boolean objectValue) [0x00000] 
in <filename unknown>:0 
  at System.Runtime.Serialization.Json.JsonReader.Read () [0x00000] in <filename unknown>:0 
  at System.Xml.XmlReader.Skip () [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.Json.TypeMap.Deserialize 
(System.Runtime.Serialization.Json.JsonSerializationReader jsr) [0x00000] in 
<filename 
unknown>:0 
  at System.Runtime.Serialization.Json.JsonSerializationReader.ReadObject (System.Type type) 
[0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.Json.JsonSerializationReader.ReadRoot () [0x00000] in 
<filename unknown>:0 
  at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject 
(System.Xml.XmlReader reader, Boolean verifyObjectName) [0x00000] in <filename 
unknown>:0 
  --- End of inner exception stack trace ---
  at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject 
(System.Xml.XmlReader reader, Boolean verifyObjectName) [0x00000] in <filename 
unknown>:0 
  at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject 
(System.Xml.XmlDictionaryReader reader, Boolean verifyObjectName) [0x00000] in 
<filename 
unknown>:0 
  at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject 
(System.Xml.XmlDictionaryReader reader) [0x00000] in <filename unknown>:0 
  at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject (System.IO.Stream 
stream) [0x00000] in <filename unknown>:0 
  at ServiceStack.Client.JsonDataContractDeserializer.Parse (System.String json, System.Type 
returnType) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at ServiceStack.Client.JsonDataContractDeserializer.Parse (System.String json, System.Type 
returnType) [0x00000] in <filename unknown>:0 
  at ServiceStack.Client.JsonServiceClient.Send[GetPropertyByGuidResponse] (System.Object 
request) [0x00000] in <filename unknown>:0 
  at iNorc.PropertyDetailsView.ViewDidLoad () [0x00000] in <filename unknown>:0 
  at (wrapper managed-to-native) 
MonoTouch.ObjCRuntime.Messaging:void_objc_msgSend_IntPtr_Boolean 
(intptr,intptr,intptr,bool)
  at MonoTouch.UIKit.UINavigationController.PushViewController 
(MonoTouch.UIKit.UIViewController viewController, Boolean animated) [0x00000] 
in <filename 
unknown>:0 
  at iNorc.PropertyCalloutBubbleDelegate.RowSelected (MonoTouch.UIKit.UITableView tableView, 
MonoTouch.Foundation.NSIndexPath indexPath) [0x00000] in <filename unknown>:0 
  at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain 
(int,string[],intptr,intptr)
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, 
System.String delegateClassName) [0x00000] in <filename unknown>:0 
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args) [0x00000] in <filename 
unknown>:0 
  at iNorc.Application.Main (System.String[] args) [0x00000] in <filename unknown>:0 

I am using the ServiceStack v1.10 library on a Windows 2008 Machine and the 
ServiceStack client 
library provided with the example RemoteInfo.zip, on an iPhone Simulator 
platform.

The issue might  very well be with the Mono framework itself. However, i was 
able to get the 
deserialization code working after changing line 19 from 
JsonDataContractSerializer.cs from the 
ServiceStack.Client assembly from:

var bytes = Encoding.Unicode.GetBytes(json);

to

var bytes = Encoding.UTF8.GetBytes(json);

While analyzing the serialization code from 
ServiceStack.ServiceModel.Serialization.JsonDataContractSerializer, i saw that 
the stream reader 
used to serialize the object has no explicit encoding, therefore using the 
default UTF8 ecoding. 

On the other hand, the deserialization is made by converting the json string to 
a byte array using  
Unicode encoding (which is UTF-16). 

So, while i see no issues with the server deserializing it properly (as it also 
uses Unicode to 
deserialize an object serialized as an UTF-8 encoded string from the MonoTouch 
application), 
the response cannot be properly deserialized back.

My suggestion is to either use explicit encodings on both ends or to employ 
some kind of 
encoding detection mechanism (see 
http://www.west-wind.com/WebLog/posts/197245.aspx 
for an example).

Original issue reported on code.google.com by alexandr...@gmail.com on 5 Apr 2010 at 12:33

GoogleCodeExporter commented 9 years ago
Hi, sorry I haven't replied sooner - only stumbled across reading this issue 
now as it didn't get emailed to me automatically.

It is very odd that I'm using 'Encoding.Unicode' because I normally standardize 
on 'Encoding.UTF8' whenever possible, the only reason I can think I would've 
changed it is because I 
had problems with 'UTF8'. Anyways the default should be 'UTF8' so I've changed 
it back, I've added some serialization tests around this and it doesn't look 
like it has affected the 
.NET release, so it will be available in the next release on the weekend.

PS: I have just added a new optimized and compact 'JSV' endpoint that I 
intended to use for perf/bandwidth constrained .NET to .NET environments like 
MonoTouch which you can read 
more about here: http://www.servicestack.net/mythz_blog/?p=176
Hopefully I'll have time to get this weekend to test it inside MonoTouch, due 
to the AOT limitations it will probably require a manual RegisterType<T> step 
so the code for 
serialization/de-serialization can be compiled ahead-of-time but I think the 
perf gains will make it worthwhile. 

Original comment by demis.be...@gmail.com on 15 Apr 2010 at 1:15

GoogleCodeExporter commented 9 years ago

Original comment by demis.be...@gmail.com on 11 May 2010 at 11:34

GoogleCodeExporter commented 9 years ago
Was this issue fully resolved?  I'm getting the same error. I am new to 
ServiceStack; I just downloaded it today (version 2.05, uploaded 3/4/2011).  
I'm working in MonoTouch and using JsonDataContractDeserializer.  Here's the 
full text of what I'm deserializing:

{"ContextList":[],"DisplayString":"Testing: 
David","Exception":null,"ExceptionString":null}

Original comment by dave.ca...@gmail.com on 14 Mar 2011 at 5:53

GoogleCodeExporter commented 9 years ago
So this project is closed at this site, if you want to report an issue please 
do so at:
https://github.com/ServiceStack/ServiceStack.Text/issues

Original comment by demis.be...@gmail.com on 14 Mar 2011 at 8:48