Cannot deserialize type without setter - c#

I have binary serialized objects in database. They are serialized with protobuf.
Now I need to generate some viewer to see the content of Database.
So, i read stream from database and deserialized it back to the objects.
It works and the result is list of objects:
var dbData = readData(someType);//it is IList collection
Now, I would like to save this list of objects to file to see the content of database. I thought it would be the best to save it to xml. So, i have tried:
var serializer = new XmlSerializer(dbData.GetType());
But i get an error: Cannot deserialize type 'My.Entities.IdBase' because it contains property 'Key' which has no public setter.
What now? I can't change the class definitions to have setters.
Should i save objects to json or plain text instead? Or should i extract all properties and values and save it to some xml? Any code example?

JSON.NET would be the answer here. You can find it in nuget. Use it like this:
JsonConvert.DeserializeObject<T>(input);

Related

Serialize "JsValue" in Jint

At the moment, I'm trying to figure out how to save a Jint.NET JavaScript environment to file, so I can load it again later.
However, I'm having major trouble trying to serialize/deserialize the Jint.Native.JsValue class. Since it has no constructor, Newtonsoft doesn't like deserializing to it, and when serializing, it ignores all private properties, resulting in only the Type field being saved.
string saved = JsonConvert.SerializeObject(someJsValue); //output: {Type: x}
JsonConvert.DeserializeObject<JsValue>(saved); //error: no constructor
Is there any way around this so I can load/save this properly?

How do I use a JSON string as variable data for a Liquid.NET template?

I'm looking for the best way to use a JSON string as the variable data for a Liquid.NET template. I don't know the structure of the JSON so I am unable to deserialize it to a POCO before using it.
I attempted to use the .ToLiquid() extension method on a JSON.Net JObject but it throws a memory exception.
I may need to convert the JSON to a LiquidHash before merging it with the template. Is there a utility that provides this or do I need to iterate over all the nodes myself?
https://github.com/mikebridge/Liquid.NET
You currently need to generate a LiquidHash manually.

Querying RavenDB with a reflected type

I load types dynamically through reflection, instantiate the classes, fill them with data and then save them to RavenDB. They all implement an interface IEntity.
In the RavenDB UI, I can see the classes correctly displayed and the meta data has the correct CLR type.
Now I want to get the data back out, change it and then save it.
What I'd like to do
I have the System.Type that matches the entity in RavenDB's CLR meta data, assuming that's called myType, I would like to do this:
session.Query(myType).ToList(); // session is IDocumentSession
But you can't do that, as RavenDB queries like so:
session.Query<T>();
I don't have the generic type T at compile time, I'm loading that dynamically.
Solution 1 - the Big Document
The first way I tried (for a proof of concept) was to wrap all the entities in a single data object and save that:
public class Data {
List<IEntity> Entities = new List<IEntity>();
}
Assuming the session is opened/closed properly and that I have an id:
var myDataObject = session.Load<Data>(Id);
myDataObject.Entities.First(); // or whatever query
As my types are all dynamic, specified in a dynamically loaded DLL, I need my custom json deserializer to perform the object creation. I specify that in the answer here.
I would rather not do this as loading the entire document in production would not be efficient.
## Possible solution 2 ##
I understand that Lucene can be used to query the type meta data and get the data out as a dynamic type. I can then do a horrible cast and make the changes.
Update after #Tung-Chau
Thank you to Tung, unfortunately neither of the solutions work. Let me explain why:
I am storing the entities with:
session.Store(myDataObject);
In the database, that will produce a document with the name of myDataObject.GetType().Name. If you do:
var myDataObject = session.Load<IEntity>(Id);
Then it won't find the document because it is not saved with the name IEntity, it is saved with the name of the dynamic type.
Now the Lucene solution doesn't work either but for a slightly more complex reason. When Lucene finds the type (which it does), Raven passes it to the custom JsonDeserialiser I mentioned. The custom Json Deserialiser does not have access to the meta data, so it does not know which type to reflect.
Is there a better way to retrieve data when you know the type but not at compile time?
Thank you.
If you have an ID (or IDs):
var myDataObject = session.Load<IEntity>(Id);
//change myDataObject. Use myDataObject.GetType() as you want
//....
session.SaveChange();
For query, LuceneQuery is suitable
var tag = documentStore.Conventions.GetTypeTagName(typeof(YourDataType));
var myDataObjects = session.Advanced
.LuceneQuery<IEntity, RavenDocumentsByEntityName>()
.WhereEquals("Tag", tag)
.AndAlso()
//....

c# How to deserialise from an XML file and display the properties in a windows form?

I have an XML file and and a class representing the XML structure. I have deserialized the XML file into the class. I want to display all the properties into the form. Can anyone suggest if it is possible and how to deserialize the XML into datagridview?
For the most part, de-serialization involves have a valid class structure and or object to de-serialize the thing into, whether that is Xml deserialization, or Binary, or SOAP...etc etc. You have the class, so the de-serialize step will be simple enough, just create the serializer and call deserialize(xml). As for the second part...well, you have to create a datagridview and bind to the object.
so, yes, totally possible. without access to the object, the class definition, or the xml, this is all the information I can give you.
Some basic code structure.
XmlSerializer ser = new XmlSerializer(typeof(MyClass));
MyClass obj = ser.DeSerialize(xmlDoc);
MyDataGridView.DataSource = obj;

Default entries on a first time creation for a serialized class

I have a class I am using for serializing various configuration options for an application I am working on. I'm adding a new property to the class that is a List, and I'd like it to fill this list if it does not exist already in a XML file. My first thought was to check if the list contained zero items, however this is not acceptable because there are times I want to have zero items in the list. In essence I want a file that has been serialized with an older version of the same class to be "upgraded" and have defaults automatically inserted for new properties. How can I do this? For a more visual example of what I'm trying to do, see below:
When I deserialize an XML file that contains:
<Item1>wtfe</Item1>
<Item2>wtfe</Item2>
and after I've added a list property it will serialze as:
<Item1>wtfe</Item1>
<Item2>wtfe</Item2>
<Item3/>
I want it to serialize as:
<Item1>wtfe</Item1>
<Item2>wtfe</Item2>
<Item3>
<DefaultSubItem/ Field="wtfe">
<DefaultSubItem/ Field="wtfe">
</Item3>
But allow me to change it to:
<Item1>wtfe</Item1>
<Item2>wtfe</Item2>
<Item3></Item3>
Another option may be to use these attributes:
[OnSerializing()]
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.onserializingattribute.aspx
[OnDeserializing()]
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializingattribute.aspx
I think your looking for the SerializationBinder class:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationbinder%28VS.71%29.aspx

Categories

Resources