[DataContract]
public class Person
{
[DataMember(Name="id")] public long PersonID { get; set; }
[DataMember(Name="first")] public string FirstName { get; set; }
[DataMember(Name="last")] public string LastName { get; set; }
}
// respect DataContracts on the way in
var reader = new JsonReader(new DataReaderSettings(new DataContractResolverStrategy()));
// use convention over configuration on the way out
var writer = new JsonWriter(new DataWriterSettings(new ConventionResolverStrategy(ConventionResolverStrategy.WordCasing.Lowercase, "-")));
string input =
@"[
{ ""id"": 1, ""first"": ""Foo"", ""last"": ""Bar"" },
{ ""id"": 2, ""first"": ""etc."", ""last"": ""et al."" },
{ ""id"": 3, ""first"": ""Blah"", ""last"": ""Yada"" }
]";
var people = reader.Query<Person>(input);
var query =
from person in people.ArrayItems()
where person.PersonID == 1 || person.FirstName == "Blah"
orderby person.PersonID
select person;
Console.WriteLine(query.Last().LastName); // Yada
string json = writer.Write(query);
Console.WriteLine(json); // [{"person-id":1,"first-name":"Foo","last-name":"Bar"},{"person-id":3,"first-name":"Blah","last-name":"Yada"}]
Serialize to/from TCP socket:
TcpClient tcpClient = new TcpClient(server, port);
NetworkStream tcpStream = tcpClient.GetStream();
// read incrementally from incoming stream
TextReader tcpReader = new StreamReader(tcpStream);
Foo myFoo = new JsonReader.Read<Foo>(tcpReader);
// write directly to output stream
TextWriter tcpWriter = new StreamWriter(tcpStream);
new JsonWriter.Write(myFoo, tcpWriter);
Fully customizable name resolution strategies
// accept all variations! list in order of priority
var resolver = new CombinedResolverStrategy(
new JsonResolverStrategy(), // simple JSON attributes
new DataContractResolverStrategy(), // DataContract attributes
new XmlResolverStrategy(), // XmlSerializer attributes
new ConventionResolverStrategy(ConventionResolverStrategy.WordCasing.PascalCase), // DotNetStyle
new ConventionResolverStrategy(ConventionResolverStrategy.WordCasing.CamelCase), // jsonStyle
new ConventionResolverStrategy(ConventionResolverStrategy.WordCasing.Lowercase, "-"), // xml-style
new ConventionResolverStrategy(ConventionResolverStrategy.WordCasing.Uppercase, "_")); // CONST_STYLE
// pass the combined resolver strategy into the settings object
var reader = new JsonReader(new DataReaderSettings(resolver));
// link the settings objects to share resolver strategies and name lookup cache
var writer = new JsonWriter(new DataWriterSettings(reader.Settings) { PrettyPrint=true });
Build REST services using dependency injection to configure auto-serializer selection
// setup once for the lifespan of the application
// POCO name resolution, share lookups among all instances
var readerSettings = new DataReaderSettings();
var writerSettings = new DataWriterSettings(readerSettings);
var jsonReader = new JsonFx.Json.JsonReader(readerSettings);
var jsonWriter = new JsonFx.Json.JsonWriter(writerSettings);
var xmlReader = new JsonFx.Xml.XmlReader(readerSettings);
var xmlWriter = new JsonFx.Xml.XmlWriter(writerSettings);
// list all the readers
var readerProvider = new DataReaderProvider(
jsonReader,
xmlReader);
// list all the writers
var writerProvider = new DataWriterProvider(
jsonWriter,
xmlWriter);
// ...later on a request comes in
// incoming HTTP request headers
string contentTypeHeader = myRequest.Headers[HttpRequestHeader.ContentType];
string acceptHeader = myRequest.Headers[HttpRequestHeader.Accept];
IDataReader deserializer = readerProvider.Find(contentTypeHeader);
var requestData;
using (var textReader = new StreamReader(myRequest.GetRequestStream()))
{
requestData = deserializer.Read(textReader);
}
// ...consume the data, generate a response
var myResponse = ...;
var responseData = ...;
IDataWriter serializer = writerProvider.Find(acceptHeader, contentTypeHeader);
using (var textWriter = new StreamWriter(myResponse.GetResponseStream()))
{
serializer.Write(responseData);
}
I've got an issue with consuming a Drupal JSON service.
Drupal is a CMS in which each content node has a body text. If body of value "Lorem ipsum" is entered, the (part of) response of Drupal's REST service is the following:
However, if you leave the body blank, the response becomes:
"body":[]
I'm using the following structure on the .NET side:
[JsonFx.Json.JsonName("body")]
public Dictionary<string, BodyValue[]> Body = new Dictionary<string, BodyValue[]>();
... where BodyValue is:
public class BodyValue : SafeValueBase
{
[JsonFx.Json.JsonName("value")]
public string Value;
[JsonFx.Json.JsonName("format")]
public string Format;
[JsonFx.Json.JsonName("safe_value")]
public string SafeValue;
[JsonFx.Json.JsonName("summary")]
public string Summary;
[JsonFx.Json.JsonName("safe_summary")]
public string SafeSummary;
}
In the case of the blank body I'm getting the exception:
JsonFx.Json.JsonTypeCoercionException: Error converting System.Object[] to System.Collections.Generic.Dictionary2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[BodyValue[], eDriven.Drupal7, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] ---> System.InvalidCastException: Value is not a convertible object: System.Object[] to System.Collections.Generic.Dictionary2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[BodyValue[], eDriven.Drupal7, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
at System.Convert.ToType (System.Object value, System.Type conversionType, IFormatProvider provider, Boolean try_target_to_type) [0x00000] in :0
I'm interested if this issue could be solved on the JsonFx side somehow. I'm thinking of some kind of fall-back options (something like: "if body is not an object, then try to deserialize it as array...")
Hi, I wonder if there is already support for this requirement.
class Location{
public string Name{get;set;}
}
class Session{
public Location Location{get;set;}
}
Location l = new Location(){Name="test"};
Session session = new Session(){Location=l};
As part of a project I’ve been using the JsonFx library. It is great to use and I’m still very positive about it.
However, I’ve been having an issue. Whenever I try to serialize a collection (both generic and non-generic) using the Mono Framework, I encounter the following exception:
Unhandled Exception: JsonFx.Serialization.SerializationException: Invalid IL cod
e in (wrapper dynamic-method) object: (object): IL_0001: callvirt 0x00000001
---> System.InvalidProgramException: Invalid IL code in (wrapper dynamic-method
) object: (object): IL_0001: callvirt 0x00000001
at (wrapper managed-to-native) System.Delegate:CreateDelegate_internal (System
.Type,object,System.Reflection.MethodInfo,bool)
at System.Delegate.CreateDelegate (System.Type type, System.Object firstArgume
nt, System.Reflection.MethodInfo method, Boolean throwOnBindFailure, Boolean all
owClosed) [0x0032c] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.1\mcs\class
\corlib\System\Delegate.cs:260
at System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodI
nfo method, Boolean throwOnBindFailure) [0x00000] in C:\cygwin\tmp\monobuild\bui
ld\BUILD\mono-2.10.1\mcs\class\corlib\System\Delegate.cs:273
at System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodI
nfo method) [0x00000] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.1\mcs\cla
ss\corlib\System\Delegate.cs:278
at System.Reflection.Emit.DynamicMethod.CreateDelegate (System.Type delegateTy
pe) [0x0002f] in C:\cygwin\tmp\monobuild\build\BUILD\mono-2.10.1\mcs\class\corli
b\System.Reflection.Emit\DynamicMethod.cs:168
at JsonFx.CodeGen.DynamicMethodGenerator.GetPropertyGetter (System.Reflection.
PropertyInfo propertyInfo) [0x00000] in <filename unknown>:0
at JsonFx.Serialization.Resolvers.MemberMap..ctor (System.Reflection.PropertyI
nfo propertyInfo, DataName dataName, JsonFx.Serialization.Resolvers.ValueIgnored
Delegate isIgnored) [0x00000] in <filename unknown>:0
at JsonFx.Serialization.Resolvers.ResolverCache.BuildMap (System.Type objectTy
pe, IDictionary`2& maps) [0x00000] in <filename unknown>:0
at JsonFx.Serialization.Resolvers.ResolverCache.LoadTypeName (System.Type type
) [0x00000] in <filename unknown>:0
at JsonFx.Model.ModelWalker.GetTypeName (System.Object value) [0x00000] in <fi
lename unknown>:0
at JsonFx.Model.ModelWalker.GetArrayTokens (System.Collections.Generic.List`1
tokens, ICycleDetector detector, IEnumerable value) [0x00000] in <filename unkno
wn>:0
at JsonFx.Model.ModelWalker.GetTokens (System.Collections.Generic.List`1 token
s, ICycleDetector detector, System.Object value) [0x00000] in <filename unknown>
:0
at JsonFx.Model.ModelWalker.GetObjectTokens (System.Collections.Generic.List`1
tokens, ICycleDetector detector, DataName typeName, IDictionaryEnumerator enume
rator) [0x00000] in <filename unknown>:0
at JsonFx.Model.ModelWalker.GetArrayTokens (System.Collections.Generic.List`1
tokens, ICycleDetector detector, IEnumerable value) [0x00000] in <filename unkno
wn>:0
at JsonFx.Model.ModelWalker.GetTokens (System.Collections.Generic.List`1 token
s, ICycleDetector detector, System.Object value) [0x00000] in <filename unknown>
:0
at JsonFx.Model.ModelWalker.GetTokens (System.Object value) [0x00000] in <file
name unknown>:0
at JsonFx.Serialization.DataWriter`1[JsonFx.Model.ModelTokenType].Write (Syste
m.Object data) [0x00000] in <filename unknown>:0
--- End of inner exception stack trace ---
The weird thing is that in the .NET framework, everything works fine!
I’m using the following bit of code to convert the object to JSON:
dynamic el = new ElasticObject();
el.test = "value";
List<Dictionary<string, object>> result = new List<Dictionary<string, object>>(); // Usually a result from a MySQL query
el.result = result;
Hashtable jsonObject = DynamicExtensions.HashtableFromElastic(el);
JsonFx.Json.JsonWriter writer = new JsonFx.Json.JsonWriter();
string jsonString = writer.Write(jsonObject);
Using:
Latest signed .NET 4.0 build (version 2.0.0.0 according to the properties)
Mono 2.10.1
Ubuntu 10.04, but it also occurs on Windows 7 (still using Mono of course)
I see on the readme that streaming operations are supported in JsonFx, but after a quick read through the examples and scanning the source, it's not clear what the recommended approach for this is.
Do you have any similar 5-10 liners (if that's even possible) that might show how to receive JSON data streaming in incrementally over a TCP socket connection? In my case, this is not over HTTP so I won't necessarily have the entire json object when I start parsing.
Not too long ago, we chose JsonFx 2 as it seemed to best serve our needs, as we recently moved fully to .NET 4, including C# 4 and dynamics, in our daily code. JsonFx 2 definitely delivers when it comes to ease and transparency of use, however I believe we have encountered a discrepancy in how it serializes dynamic objects to Xml. Our current need involves serializing an object that has a set of predefined, required properties, and a dynamic set of optional properties. The object needs to be serialized to XML with a specific xmlns, and the optional properties, if there are any, need to be included in the serialized output.
To solve this problem, we created a custom class that derives from DynamicObject. This class is decorated with an XmlRoot attribute that defines a custom xml namespace. Using XmlSerializer, we can ensure that the xmlns is included in the root element, however it does not serialize any dynamic properties. Using JsonFx (and some careful crafting of our custom dynamic object), we can ensure that all dynamic content is serialized, however the xmlns is not output.
Is there some way to force JsonFx 2 to output xml properly in this case? By that, we need both the xmlns to be included in the header, as well as include all dynamic and static properties.
This is an issue similar to issue #28. When I tried to deserialize to a NET data type with properties which is of an interface or abstract classs, the deserialization will failed.
If you think about #28 and this issue, so this is not some rare cases that you won't run into. Especially when you are doing some serious programming, it's common practice to use interfaces. And this issue right now is a big headache for us since we are using interfaces almost everywhere.
I was playing around with the Windows 8 Consumer Preview and I wanted to use EasyHttp which depends on JsonFx.
I can't however, because NuGet won't allow me to add the package because of version limitations.
Thanks for this great library. I am using it in a Unity project connecting to an API, where authentication is controlled. From the API I receive an authentication with an expiry date as well. The expiry date is formatted as ".expires", but JsonFX does not allow that.
EcmaScriptIdentifier.cs, line 148 splits on dot for nesting meaning that I get an ArgumentException: Variable expiression ".expires" is not supported.
I guess there is no reason not to allow properties starting with a dot? The bug probably occurs do to the fact that ".expires" is recognized as a nested property, which it is not. I am not sure where this check is performed, but fixing this nested-check should do the trick I think.
Using the JsonReader with the DataContractResolverStrategy the serializers does not seem to serialize into the ExtensionDataObject if the contract implements IExtensibleDataObject.
The serializedItem and otherSerializedItem will not be the same as the serializedItem will have all the unknown values in the ExtensionDataObject defined in the contract.
I don't know if this would be a desired feature, an option to the resolver strategy or whatnot - but I find it odd that the two produces different results (and I for one finds it a usefull feature).
You should package 2.0 for [http://nuget.org NuGet] not only does it make it easy to consume and update your framework from within visual studio, but you only need one package for all target runtime frameworks.
Hi! Is it possible to change property name while desirializing object?
Something like this (but this doesn't work)
private class Resolver : JsonFx.Serialization.Resolvers.PocoResolverStrategy
{
...
public override IEnumerable<JsonFx.Serialization.DataName> GetName(MemberInfo member)
{
//????
change property name here
return base.GetName(member);
}
}
JsonFx.Serialization.DataReaderSettings sgs = new JsonFx.Serialization.DataReaderSettings(new Resolver());
I have a StreamReader(MyNetworkStream()) that gets passed into JsonReader.Read. My network connection is persistent, so I would like to keep the StreamReader around until it gets closed.
In JsonTokenizer.GetTokens(), the TextReader gets disposed once a single JSON object is complete. This is a problem (I think) since some of the next JSON object's data might be buffered in that reader, so even if I create a new StreamReader, the data has already been read out of the NetworkStream. The error I saw in this case was that JsonTokenizer threw exceptions with ErrorUnrecognizedToken when reading from a StreamReader created after the first one had been disposed, even though the input was good.
If I comment out 'scanner.Dispose()' in JsonTokenizer, my app runs as expected, and I can dispose it myself once the socket closes.
Side note: the JsonFx solution file doesn't open up by default in Visual Studio Express 2010, or MonoDevelop - I had to edit around manually before they worked, and then had to add an explicit reference to System.Xml before JsonFx would compile. Would be nice if it were a little easier to hack on :)
My JsonFX serialization code works, but the object that I'm serializing contains a list of polymorphic entities, and they're all deserialized as their base type and not their actual type.
As you can see it's pretty straightforward. I'm also not decorating my classes with any attributes or anything special to make them serializable. Besides the polymorphic problem, it all just seems to be working properly.
So how can I get my polymorphic types to deserialize properly?.
We have a mix of resources, most of them are JSON, however in some cases we have had to request results as XML due to incorrect JSON serialization on the server side. When we receive xml results back, they usually have a standard xml header:
When deserializing such XML content with JsonFX 2, we get a dynamic object back that contains three properties:
That is obviously incorrect. We could care less about the xml header, we need access to the content within the actual XML body. Additionally, if the string being deserialized contains ANY preceeding whitespace of any kind before the first angle bracket of the root element, JsonFx 2 simply spits out that white space as a string wrapped in a dynamic, and ignores the actual XML body. For example, if the XML content contained two spaces and two returns before the first angle bracket of the XML, the object returned from JsonFX would be:
" \n\n"
Intriguingly enough, this is a Windows operating system, so one would expect hard returns to be encoded as "\r\n", rather than simply "\n". Either way, JsonFX does seem to have some problems deserializing XML content. It does not appear to sanitize input before trying to parse, and is incapable of handling a standards-compliant XML header. It would be extremely helpful if these issues were fixed soon.
I'm not an expert in your serializer, so the tests are not so good as they have to be for your serializer.
It would be great if you look to the test code https://github.com/leo-gan/GLD.SerializerBenchmark
and maybe optimize it for the better performance.
Thank you for your great serializer!
Leo
I have a class that have 4 or 5 conditionnal property. one of them is not working.
Here are two. the conditional serialization works with normals (it is not serialized if the attribute is null) but it triggers an exception with the material.
[JsonFx.Json.JsonIgnore]
public float[] normals;
[JsonFx.Json.JsonSpecifiedProperty("isNormalsNotEmpty")]
[JsonFx.Json.JsonName("normals")]
public string compressed_normals
{
get
{
return JiEncoder.toString(JiEncoder.encodeSingleArray(normals, 0));
}
set
{
normals = JiEncoder.decodeSingleArray(JiEncoder.fromString(value));
}
}
[JsonFx.Json.JsonIgnore]
public bool isNormalsNotEmpty
{
get
{
return normals != null;
}
}
[JsonFx.Json.JsonIgnore]
public MaterialMsg material;
[JsonFx.Json.JsonIgnore]
public bool isMaterialNotNull
{
get {
return material != null;
}
}
[JsonFx.Json.JsonSpecifiedProperty("isMaterialNotNull")]
[JsonFx.Json.JsonName("material")]
public string json_material
{
get {
return material.ToJson ();
}
set {
//Console.WriteLine ( value );
material = (value.Contains ( "UVscale" )) ? SapphireMaterialMsg.FromJson<SapphireMaterialMsg> ( value ) : MaterialMsg.FromJson<MaterialMsg> ( value );
}
}`
JsonFx.Serialization.SerializationException : Object reference not set to an instance of an object.
----> System.NullReferenceException : Object reference not set to an instance of an object.
JsonFx.Serialization.SerializationException: Operation could destabilize the runtime. ---> System.Security.VerificationException: Operation could destabilize the runtime.
at (Object )
at JsonFx.Model.ModelWalker.GetObjectTokens(List'1 tokens, ICycleDetector detector, Type type, Object value)
at JsonFx.Model.ModelWalker.GetTokens(List'1 tokens, ICycleDetector detector, Object value)
at JsonFx.Model.ModelWalker.GetTokens(Object value)
at JsonFx.Serialization.DataWriter`1.Write(Object data)
On call: object propertyValue = map.Getter(value);
We are in the process of trying to figure out which json parser to use
for our unity project that will work on the web, iOS and Android. We
need something lightweight and fast and that doesn't use reflection (iOS
issue).
I have several custom web services that send json formatted data to the
client, but we are having a big of a hard time getting up and running
with your system since we tested litjson and things get turned easily
into a dictionary. Right now based upon our data coming from the server
we need to write a method to make sure an int is coming though, a string
etc..
Do you have any example code or maybe example code with Unity that we
could look at and what is the best method for us to deal with various
json methods of data we send to the client. Currently we have 15 call
types that return various types of data.
any help would be appreciated.
thanks
we are seeing this issue quite often with some test..
Failed processing communications response:
System.ExecutionEngineException: Attempting to JIT compile method 'JsonFx.Serialization.DataReader1<JsonFx.Model.ModelTokenType>:Read<System.Collections.Generic.Dictionary2<string, object>> (string)' while running with --aot-only
The following code works as expected (showing "Number of tweets = 2") when reading the input into a string before parsing. When the StreamReader is used directly it fails with "Unterminated JSON string".
JsonFx version 2.0.1106.2515
Bug or feature? Am I doing something wrong?
static void JsonReadFailure()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://api.twitter.com/1/statuses/user_timeline.json?screen_name=JornWildt&count=2");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
JsonReader jsr = new JsonReader();
using (TextReader reader = new StreamReader(response.GetResponseStream()))
{
#if true
dynamic result = jsr.Read(reader);
#else
string json = reader.ReadToEnd();
dynamic result = jsr.Read(json);
#endif
Console.WriteLine("Number of tweets = {0}.", result.Length);
}
}
The following minimal program shows up an obscure issue I ran into by accident;
using System; using System.Collections.Concurrent; using System.Collections.Generic; using JsonFx.Json; namespace JsonFXTest{ class Program{ static void Main(){ IDictionary<int, object> dict = new ConcurrentDictionary<int, object>(); dict.Add(1, new object()); string json = new JsonWriter().Write(dict); Console.WriteLine(json); }}}
Executing this terminates the program at the serialisation step with no stack trace and the following Error events added to the Application event log;
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> <System> <Provider Name=".NET Runtime" /> <EventID Qualifiers="0">1023</EventID> <Level>2</Level> <Task>0</Task> <Keywords>0x80000000000000</Keywords> <TimeCreated SystemTime="2016-05-27T16:24:28.442474700Z" /> <EventRecordID>139541</EventRecordID> <Channel>Application</Channel> <Security /> </System> <EventData> <Data>Application: JsonFXTest.exe Framework Version: v4.0.30319 Description: The process was terminated due to an internal error in the .NET Runtime at IP 00007FFB999612E0 (00007FFB99960000) with exit code 80131506.</Data> </EventData> </Event>