Someone send JSON to me. It has same format each time. It can be deserialised into dynamic object with var dyn = JsonConvert.DeserializeObject<dynamic>(rawJson);. Documentation is bad for my current version or JSON provider while I want to have code-hilighting on all the fields I get.
How to get C# class code from dynamic object so that I could then deserialise into that generated type instead of dynamic object with var oldschool = JsonConvert.DeserializeObject<GeneratedTypeFromDynamicObject>(rawJson);?
Generating a type at run-time isn't going to help you much because you need the type at compile time in order to get early binding, type safety, and Intellisense. A much more practical idea would be to do the following:
Get a representative sample of a JSON string from your logs.
Paste the JSON into a class and save it as c# code in your project.
Start using the class as the type argument to your deserialization call.
After you do this, you will have the correct class in your code base and you can compile against it. If the folks that send you the JSON decide to change the message, any new fields will be ignored. If they start removing things though then you have problems, just as if they had changed the WSDL for a SOAP service. You will have to repeat the above steps, and correct any breaking changes in your code. The nice thing is that you will have the breaking changes to guide you at compile time :)
Related
Here's my situation: I have an MVC3 app that has some very complex C# objects, and those get rendered to a views in this application. However, I have a new requirement: a console application (that I am also writing) will run under a scheduler, and it needs to pull these objects from this MVC3 app, and then do something else with these complex objects.
Since I have control over both apps, I can share a library of the complex objects between them. All of these objects are marked [Serializable]. However, I cannot figure out an easy way to serialize these objects and send them from the MVC3 app to the Console app.
I tried simple JavaScriptSerializer and using the HttpClient to read the string, then deserialize it on the console-app end of things, but unfortunately it doesn't deserialize the data correctly. Everything is null. I can inspect the string on a breakpoint when it arrives at the console app, and all the data is there, in the string, but it just doesn't get de-serialized correctly.
Is there an easier way to do this? I don't care what the serialization method is. The data doesn't have to be passed as JSON and no other application but mine is going to consume these objects. But so far I can't figure out the easiest way to produce/consume these objects.
I know I can go down the whole "create a web service contract" and use data annotations route, but I was hoping there was an easier, less time-consuming way of doing it.
Using Json.NET:
Server-Side
string serializedObject = JsonConvert.SerializeObject(yourComplexObject);
// Send the string to the client...
Client-Side
In the client, you don't even have to know the deserialized object's type, you can take advantage of anonymous objects and dynamic:
string serializedObject = // ... Fetch from server
dynamic complexObject = JsonConvert.DeserializeObject(serializedObject);
// ...
string id = complexObject.UserId;
P.S.: Please note that the object's methods or state is not going to get serialized, only the public properties are.
Can your action just return your object? If so, your client code would look something like (using HttpClient)
var result = client.GetAsync(url).Result;
var myObj = await result.Content.ReadAsAsync<T>();
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 been working on a Windows Form Control project to import into a 3rd party client software using their supplied SDK. The custom control written by yet another company I am trying to load requires sign on to a server before displaying information, which can take 20-30 seconds. In order to speed things up I had the idea to pre-load information needed by the control to a text file. Since it is not a known type it is throwing errors when trying to serialize the class.
I have a Dictionary I am using to reference back to the proper ICamera class. If I change "cam" from an ICamera type to a string, for example "cam.GetLiveURL()". It writes the text file without issue. This is the code I am using to populate the Dictionary.
foreach (ICamera cam in _adapter.Cameras())
{
OCCamera.Add(cam.GetDisplayName(), cam);
}
I have tried XMLSerializer, and it seems it has difficulty dealing with a Dictionary.
I have tried BinaryFormatter and get the error:
Type 'OCAdapter.OCCamera' in Assembly 'OCAdapter.dll' in not marked as serializable.
I have tried DataContractSerializer and get the error:
Type 'OCAdapter.OCCamera' with data contract name
'OCCamera:http://schemas.datacontract.org/2004/07/OCAdapter' is not
expected. Consider using a DataContractResolver or add ant types not
known statically to the list of known types - for example, by using
the KnownTypeAttribute attribute or by adding the to the list of known
types passed to DataContractSerializer.
I have tried playing around with the DataContractResolver and can not seem to get it to work, I do not understand it at all.
The code I am using for the BinaryFormatter and DataContractSerializer are straight from MSDN or elsewhere, and test fine without the custom type.
Maybe there is a better way to handle all this, and I am missing it. I am not opposed to ditching the Dictionary route for something else, or I can rewrite any amount of other code to make this work.
Mistake 1: trying to serialize your implementation rather than the *data.
Mistake 2: using BinaryFormatter... just about ever (except maybe AppDomain marshalling)
My advice: create a simple model ("DTO" model) that just represents the data you need, but not in terms of your specific implementation (no OCAdapter.OCCamera etc). You can construct this DTO model in whatever way is convenient for whatever serialization library you like. I'm partial to protobuf-net, but many others exist. Then map to/from your DTO model and your implementation model.
Advantages:
it'll work
changes to the implementation don't impact the data; it only impacts the mapping code
you can use just about any serializer you want
you can version the data sensibly
This may be way out in left field, crazy, but I just need to ask before I go on implementing this massive set of classes.
Basically, I'm writing a binary message parser that decodes a certain military message format into an object. The problem is that there are literally hundreds of different message types and they share almost nothing in common with each other. So the way I'm planning to implement this is to create hundreds of different objects.
However, even though the message attributes share nothing in common, the method for decoding them is fairly straightforward and follows a pattern. So I'm planning to write a code generator to generate all the objects and the decode logic for each message type.
What would be really sweet is if there was some way to dynamically create an object based on some schema. It doesn't necessarily have to be XML, but XML is pretty easy to work with.
Is this possible in C#?
I would like the interface to look something like this:
var decodedMessage = MessageDecoder.Decode(byteArray);
Where the MessageDecoder figures out what type of message it is and then returns the appropriate object. It will probably return an interface which implements a MessageType Property or something like that.
Basically what I'm wondering is if there is a way to have one object called Message, which implements a MessageType Property. And then Depending on the MessageType, the Message object transforms into whatever type of message it is, so I don't have to spend the time creating all of these message types.
ExpandOobject Where you can dynamically add fields to an object.
A good starting point is here.
Is xsd.exe what you are looking for? It can take an XML file or a schema and generate the c# classes. One problem that you might encounter though is that some of the military message formats are VERY obtuse. You could end up with some very large code files.
Look at T4 templates. They let you write code to generate code, they are integrated into the IDE, and they are quite easy really.
EDIT: There is no way to do what you are after with var, because var requires the right-hand side of the assignment to be statically typed (at compile time). I suppose that you could dynamically generate that statement, then compile and run it, but that's a very painful approach.
If you have XSD's for all of the message types, then you can use xsd.exe as #jle suggests. If not, then I am curious about the following:
// Let's assume this works
var decodedMessage = MessageDecoder.Decode(byteArray);
// Now what? I don't know what properties there are on decodedMessage, so I cant do anything with it.
I am having some trouble designing my WCF service. Bassically I need the service to recieve an XML document. The xml maps to a class that was generated from xsd.exe. I was originally just had this:
public void AddDocument(string xmlString)
Then I would deserialize the xml into the generated class. I was told this is a bad idea because I am doing extra work since wcf will do the serialization for me if I just use the document class as a parameter like this:
public void AddDocument(MyGeneratedClass document)
I'm new to WCF but if I do it this way I thought I would have to create a datacontract for MyGeneratedClass. The generated class is 20,000+ lines so this would take forever.
Do I need a DataContract? Anyway I think I am missing something so I hope this makes sense and if anyone can point me in the right direction I would greatly appreciate it. Thanks!
I would use simple types if your method only requires one or two parameters, and will return only a single simple type value.
As a general rule:
If you need to pass in more than just a few (less than 5) simple types - use some kind of a Request object, otherwise your call gets unwieldy.
If you need to return more than one single simple type value, use a Response object to bundle up those values.
I would try to avoid sending and receiving XML and parse it - try to send back and forth real well structured (data) objects - much easier to deal with and type-safe and all !