I can't seem to wrap my head around JSON in C#. I use JSON.NET and usually I can figure out the class needed to convert. However in this case it's challenging: there is no name for the individual list items.
{"error":[], "result":{"currency":[[2.0, 3.0, 4.0, 5.0], [6.0, 7.0, 8.0, 9.0], ... ]}}
This is an example from memory, I hope the syntax is right.
So, when I attempt to create the classes, I don't know where to start. Say, I am interested in the result pair. Is "currency" a list of lists? How would I map the value for the list (2.0, 3.0, 4.0, 5.0) and its enclosing result?
Not sure at all...
Currency is a list of lists of double. Your Result object should look something like:
public class Result {
List<List<double>> Currency {get;set;}
}
Additionally, Visual Studio has a 'Paste Special' option under the Edit Menu that can be used to turn an XML or JSON string from the clipboard into C# classes that conform to the structure.
To avoid any probability of errors, you can do like this: copy your JSON file, go to Visual Studio=>Edit=>Paste Special=>Paste JSON as class. This will generate the classes for you.
Related
I'm trying to create a Json Parser for C# for use with Unity. Currently I'm using Json.net as the serializer and I'm having a bit of trouble. Essentially, in order to deserialize into a function, I'm using an Enum as a representation of a function pointer. the underlying code is working fine, but I'm having trouble getting the enum to map.
Essentially the object that would be created from the JSON string
"{'==': [1, 1]}"
would be
new Tuple<Enum, dynamic[]>(Enum.Equals, {1, 1})
and vice versa.
I have found this resource, but I don't think it goes quite far enough in its explanation: https://bytefish.de/blog/enums_json_net/
Essentially how do I set up Item 1 of the Tuple to be the name of Array Item 2?
One way to see JSON is as a combination of HashMaps (dictionaries), arrays and values.
When you parse a JSON into an object, that object is a combination of dictionaries, arrays, and values.
One way to represent an enum in JSON could be as follow:
{
"type": "string",
"enum: ["red", "blue", "yellow"]
}
So, perhaps you wish to extend the functionality of the library you are using to work with Tuples.
If I am not clear, please let me know.
I have a json structured like that:
{
"eventType1": {
"unitName": "nameValue",
"comment": "initial comment"
},
"eventType2": {
"comment": "initial message"
},
}
When I deserialize it the appropriate type seems to be something like Dictionary<string, <Dictionary<string,string>>> and method would look like that:
public static Dictionary<string, Dictionary<string, string>> defaultFieldDataByEvent =
JsonConvert
.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(defaultFieldDataByEventSerialized);
which looks, well, ugly. But that's exactly how I need it to extract the data - defaultFieldDataByEvent[eventType][field].
Can I encapsulate the type into something somehow or is there a different approach to such cases?
I see multiple possible options here. Hope any of these helps.
You may try to add a type alias with using directive to make code shorter, but this won't be convenient, if logic is spread across multiple files, because you will be forced to duplicate this alias.
You may try to use JObject.Parse for deserialization, staying on lower level. But as far as your json structure is pretty various, this approach may work well.
You may try to deserialize your data into ExpandoObject. It's rather similar to JObject, except you will get pretty nice dynamic code (dynamic is not a problem here since compiler won't help you with Dictionary either), but it, obviously will be less performant. You could lose your custom types information, since everything in your graph will become an ExpandoObject, but seems like that's not an issue for your case. Example may be found here.
You may try to use [JsonExtensionData] as #dbc suggested. See How to serialize a Dictionary as part of its parent object using Json.Net.
Hi I'm quite new to C# and I'm trying to make a text editor that saves and loads Plaintext formats. I've used NewtonSoft.Json NuGet package, but I'm getting an error. I've stated a string called textToLoad, which is set to a JsonConvert.DeserializeObject. Only thing is, it says it can't convert an object to a string! I tried toString(); but it still had the same error.
It is kind of hard without the code. The process of serializing and deserializing is pretty straight forward using Json.Net. So this is an example from their documentation:
YourType yourObject= new YourType();
yourObject.Property="something";
string output = JsonConvert.SerializeObject(yourObject);
//For some reason you want this to be string, but is the type you serialized in the first place
YourType textToLoad= JsonConvert.DeserializeObject<YourType>(output);
This outlines the basic works of serializing and deserializing. But we don't really know the details of your implementation.
Hope it helps.
You can't deserialize into a string like that. At simplest form you started with JSON in the form of:
{ value: "someString" }
If you want something out of it, you must deserialize and then get the value from it.
dynamic foo = JsonConvert.DeserializeObject<dynamic>(theJson);
var textToLoad = foo.value.ToString();
You must deserialize to something in order to inspect and get properties from it.
[Edit] - Perhaps I'm not understanding. But if you share code, I'll update my answer.
I have a Java application for Android that will have some static data, which will be loaded at start up. This data is generated by a C# app as a bunch of classes with lists and Dictionaries, something like this:
public class DataContainer
{
public List<A> As = new List<A>();
public Dictionary<int, B> Bs = new Dictionary<int, B>();
// ...
}
public class A
{
public int IdA;
public int IdSomething;
public DateTime dt;
//...
}
public class B
{
public int IdB;
public string Name;
List<C> Cs = new List<C>();
//...
}
public class C
{
//...
}
(The DataContainer class is the root class that contains all the data to be transferred. I then have a similar class structure in the Java project into which I want the data to be imported.)
My issue is that I can't seem to find a combination of a .NET and Java tools/libraries that would be able to write and read the same format.
I've tried JSON with DataContractJsonSerializer and then loading with GSON but that doesn't work with Dictionaries/Maps (works fine with Lists but I need the dictionaries). The .NET exporter uses format like
"Bs":[{"Key":1,"Value":{...}}, ...]
while it looks like GSON uses
{key:value,key:value,...}
I've also looked at some XML but since there isn't a standard formatting all the libraries use something different by default and I really don't want to write all the writing/parsing rules by hand. Also, JSON has much less overhead compared to XML.
So, is there some pair of libraries for .NET export and Java import that can handle nested classes with Lists and Dictionaries? The things I've managed to find were either in the other direction or did just simple one class serialization.
BTW: I'm also using Tuples for Dictionary keys, but if nothing can handle that I'll just use nested Dictionaries, that is not a big deal.
EDIT: Since I can't answer my own question due to low rep here is the solution that worked for me:
So, I've tried a few more combinations and serializing using JSon.NET on the C#/.NET side and then loading using GSON on the Java side works great, except Tuples. For example, using Tuple as a key for dictionary will get serialized as:
{ "(False, 3)" : { ... }, "(True, 1)" : { ... }, ... }
So I have to use String keys in Java for now but that is not an issue. Possible solution is to write a custom class for the Tuple in both .NET and Java.
Example code:
string serializeObject = JsonConvert.SerializeObject(dataContainer, new IsoDateTimeConverter());
File.WriteAllText("test.json", serializeObject);
and Java:
InputStream is = getResources().openRawResource(R.raw.test); // open from /res/raw/test.json
Gson gson = new Gson();
InputStreamReader r = new InputStreamReader(is);
DataContainer dc = gson.fromJson(r, DataContainer.class);
Log.i("jsondebug", dc.Packers.get(0).Something);
You can have a look at Google Protocol Buffers. Protocol buffers are Google's lingua franca for data. Below is an excerpt from Protocol Buffers Developer Guide:
Protocol buffers are a flexible, efficient, automated mechanism for
serializing structured data – think XML, but smaller, faster, and
simpler. You define how you want your data to be structured once, then
you can use special generated source code to easily write and read
your structured data to and from a variety of data streams and using a
variety of languages. You can even update your data structure without
breaking deployed programs that are compiled against the "old" format.
Protocol buffers have many advantages over XML for serializing
structured data. Protocol buffers:
are simpler
are 3 to 10 times smaller
are 20 to 100 times faster
are less ambiguous
generate data access classes that are easier to use programmatically
An XML mapping would work just fine. Serialize as XML and send it over. You'll need marshallers and unmarshallers on either end.
Java has its JAXB standard for binding XML to objects. Perhaps you can manage it if you follow that standard.
I think you need to approach this from a different perspective. Think first about a JSON or XML format that will work well with both the C# and Java side. Think of that as an API or contract between the C# and Android apps. Instead of using libraries that marshall/unmarshall according to their own formats, make the code on each side read/write to the contract you defined.
Alternatively, you might want to look into using a binary format like Apache Thrift or Protocol Buffers.
i´m trying to query a DataTable object without specifying the fields, like this :
var linqdata = from ItemA in ItemData.AsEnumerable()
select ItemA
but the returning type is
System.Data.EnumerableRowCollection<System.Data.DataRow>
and I need the following returning type
System.Data.EnumerableRowCollection<<object,object>>
(like the standard anonymous type)
Any idea?
Thanks
If I understand you correctly, you'd like to get a collection of objects that you don't need to define in your code but that are usable in a strongly typed fashion. Sadly, no you can't.
An anonymous type seems like some kind of variant or dynamic object, but it is in fact a strongly typed class that is defined at compile time. .NET defines the type for you automatically behind the scenes. In order for .net to be able to do this, it has to have some clue from the code with which to infer the type definition. It has to have something like:
from ItemA in ItemData.AsEnumerable()
select ItemA.Item("Name"), ItemA.Item("Email")
so it knows what members to define. There's no way to get around it, the information has to logically be there for the anonymous type to be defined.
Depending on why exactly your are trying to do this, there are some options.
If you want intellisense while still encapsulating your data access, you can return xml instead of a datatable from your encapsulated data access class. (You can convert data tables to xml very easily. You'll want to use the new System.Xml.Linq classes like the XElement. They're great!) Then you can use VS2008's ability to create an xsd schema from xml. Then use/import that schema at the top of your code page, and you have intellisense.
If you have to have an object an with properties for your data, but don't want to define a class/structure for them, you'll love the new dynamic objects coming in C#4.0/VB10. You have object properties based on what the sql returns, but you won't have intellisense. There is also a performance cost to this, but (a) that might not matter for your situation and (b) it actually is not so bad in some situations.
If you're just trying to avoid making a lot of classes, consider defining structs/structures on the same code file, beneath your class definition. When you add more columns to your result set, it's easy to adjust a struct with more public fields.
In short you can have any two of the following three: (a) dynamic, (b) strontly-typed objects, (3) intellisense. But not all three.
There is one way to accomplish what you want, but it required knowledge of dynamic linq. You would build the query during run-time and then use it. I am no expert and have never really played around with it, but here is a link to Scott Guthrie's blog about it - Dynamic Linq. Hope that helps.
Wade