Write CLR objects to XML with LINQ - c#

I have an ObservableCollection items. I want to convert these to XML format so that I can store them for later use. I'm a little new to LINQ and I'm not sure how to do this. I know that I need to rely on the XDocument. But I'm not sure how to execute the query and get the results into a string format.
Can somebody please provide some pointers for me? It just seems like such an easy task, I'd be surprised if it couldn't be done.
Thank you,

You need Linq to XML. I can't post a real code here since I don't know the structure of your data, but here's a dummy example:
List<Person> people = ...
var doc = new XDocument(
new XElement("People",
from p in people
select new XElement("Person",
new XAttribute("Id", p.Id),
new XElement("LastName", p.LastName),
new XElement("FistName", p.FirstName))));
doc.Save("people.xml");
Note that Linq is not the only option here. Another very good approach is XML serialization.

Using the DataContractSerializer is your best bet. It's designed to do exactly what you are asking for.
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer(v=VS.95).aspx
Advantages over XMLSerializer:
Opt-in rather than opt-out properties to serialize. This mean you specify what you want serialize
Because it is opt in you can serialize not only properties, but also fields. You can even serialize non-public members such as private or protected members. And you dont need a set on a property either (however without a setter you can serialize, but not deserialize)
Is about 10% faster than XmlSerializer to serialize the data because since you don’t have full control over how it is serialize, there is a lot that can be done to optimize the serialization/deserialization process.
Can understand the SerializableAttribute and know that it needs to be serialized
More options and control over KnownTypes
Disadvantages:
No control over how the object is serialized outside of setting the name and the order

I'm not sure what you want.
You can create a XElement and convert it to a string with the ToString method.
You can do the same with XDocument.

I'm not at all familiar with Silverlight, but it sounds like you are going to need to use XML serialization. XML serialization allows you to serialize an object into an XML representation, which you can then later deserialize from XML back into an object.
Here are some tutorials and information on XML serialization in .NET:
XML Serialization
XML Serialization Using C#
XmlSerializer class

Related

C# Serializing properties with custom values

I want to serialize a class with a lot of properties. Some of those properties are complex. There are some of the type Bitmap, Color and much more, and they do not get serialized at all.
The approach I am using is the following:
XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
MemoryStream stream = new MemoryStream();
serializer.Serialize(stream, obj);
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
XmlDocument returnDoc = new XmlDocument();
returnDoc.Load(stream);
How can I create "custom" approaches for those complex properties? Until now I created the XML-Documents myself and went trough every single property and converted it to text.
An other example where I need this is on references. This class has got some references to other classes. I don't want the whole subclass to be serialized, but only the name of it.
I am sure there are different approaches on how to accomplish this. What would be the best way to go?
I already tought of making extra properties and ignoring the others (XmlIgnore()), but that would be an overhead.
Thanks!
Your best bet is to stop trying to serialize your domain model, and create a DTO model that represents just what you want to store, in the way you want to store it (i.e. geared towards your chosen serializer).
If you want to store a bitmap, then you probably want a byte[] property. If you want to store the name of something - a string. Then just map between them. Simple, pain-free, and much easier than trying to fight a serializer into doing something that it doesn't want to do.
For properties that are not serializable you need to implement the serialization yourself. You could serialize these objects to a byte array and then use Base64 encoding to place them to XML. Check out the following link: XmlSerializer , base64 encode a String member.
However, if you do not need to serialize into XML, you can use binary serialization which will work on all properties.

How to dynamically create a JSON object in c# (from an ASP.NET resource file)?

I need to serialize the strings from a resource file (.resx) into a JSON object. The resource file's keys are in flux and thus I cannot just create a C# object that accepts the appropriate values. It needs to be a dynamic solution. I am able to loop through the key-value pairs for the file, but I need an easy way to serialize them to JSON.
I know I could do:
Object thing = new {stringOne = StringResource.stringOne; ...}
But, I'd rather have something like:
Object generic = {}
foreach (DictionaryEntry entry in StringResource) {
generic.(entry.Key) = entry.Value
}
Or should I just create a custom JSON serializer that constructs the object piecemeal (i.e. foreach loop that appends part of the JSON string with each cycle)?
EDIT
I ended up writing a quick JSON serializer that constructs the string one field at a time. I didn't want to include a whole JSON library as this is the only use of JSON objects (for now at least). Ultimately, what I wanted is probably impractical and doesn't exist as it's function is better served by other data structures. Thanks for all the answers though!
If you're using C# 4.0, you should look at the magical System.Dynamic.ExpandoObject. It's an object that allows you to dynamically add and remove properties at runtime, using the new DLR in .NET 4.0. Here is a good example use for the ExpandoObject.
Once you have your fully populated ExpandoObject, you can probably easily serialize that with any of the JSON libraries mentioned by the other excellent answers.
This sounds like an accident waiting to happen (i.e. creating output prior to cementing the structure), but it happens.
The custom JSON serializer is a compelling option, as it allows you to easily move from your dictionary into a JSON format. I would look at open source libraries (JSON.NET, etc) to see if you can reduce the development time.
I also think setting up in a slightly more structured format, like XML, is a decent choice. It is quite easy to serialize from XML to JSON using existing libraries, so you avoid heavy customization/
The bigger question is what purposes will the data ultimately serve. If you solve this problem using either of these methods, are you creating bigger problems in the future.
Probably I would use JSON.NET and the ability to create JSON from XML.
Then, you could create an XML in-memory and let JSON.NET convert it to JSON for you. Maybe if you dig deeper into the API, there are other options, too.
Newtonsoft is a library that has all kinds of nifty JSON tools...among them, on-the-fly one-line serializer and deserializers...check it out, it's my favorite JSON library out there
http://james.newtonking.com/pages/json-net.aspx
If I remember correctly, it has a class that will convert JSON to a .NET object without having to create the .NET object first. Think it is in the Json.Convert class
The way I do it is:
var serialiser = new System.Web.Script.Serialization.JavaScriptSerializer();
string json = serialiser.Serialize(data);
context.Response.Write(json);

Deserialize XML with different schemas into a shared type

Using c#, I want to deserialize xml from various sources into objects of a common type. The XML will not have the same schema. Eg, in the following xml, /thingContainer/thing/name and widget/#title both would map to myClass.DisplayName.
Xml1:
<thingContainer>
<thing>
<name>MyName</name>
</thing>
</thingContainer>
Xml2:
<widget title="myTitle" />
So, I can't mark up my class with [XmlElement], since it will be different depending on the source of my xml. Is there some trick I can do with inheritance or some helper class that will enable me to easily deserialize xml from different sources? Is there some easy way to map class fields to xpaths?
Of course, if I have to, I'll parse and manually deserialize the xml... but what fun is that?
Two thoughts that immediately spring to mind:
Use XSLT to transform the original XML into an interim format that matches your object model (a very popular approach, though personally I despise XSL)
Create interim object models to deserialize to, then map them to your final object model.
There's probably some XmlElement hackery possible, but it seems like it would be a messy approach.
I think you have two options here:
Implement IXmlSerializable for your class and deserialize taking into account the structure of your XML
Just use LINQ to XML to parse the XML and create an instance of your class. This is the approach I would pick (having gone through the first choice myself and not liking it)

How can I make XmlSerializer.Deserialize more strict?

I have some very similar XML structures which are in fact quite distinct, but it appears that XmlSerializer.Deserialize is very "forgiving" and will go out of its way to take XML and deserialize out into a strongly typed object I created from the source XSDs. Is there any way to make it more strict or do some type of deeper validation?
// Locals
var serializer = new XmlSerializer(typeof(SomeCustomType));
// Set
var someInstance = serializer.Deserialize(new StringReader(xmlString.ToString()))
#Jeff Because the root nodes are similar it will deserialize into completely different objects. Imagine that you have a house, car and boat and they all share a base root node called item with a few attributes. Even though sub-nodes are invalid and unshared it seems to overlook and forgive that.
#Will I don't want to validate against the XSD. I want to somehow cause the Deserializer to see that the data it has shouldn't be shoe-horned into the wrong Object type.
The problem was that the XML input was incorrect.
I once used validating reader to validate XML against schema as I read it into the deserializer.

Serialize C# class directly to SQL server?

can anyone suggest the best way to serialize data (a class actually) to a DB?
I am using SQL server 2008 but i presume i need to serialize the class to a string / or other data type before storing in the database?
I presume that this field needs to be text or binary??
Does SQL server 2008 (or .net 3.5) support serializing directly tothe database ??
Any help really appreciated
You can xml serialize the class into an xml field. We use this all the time for exception logging in an ETL.
Using the XmlSerializer you may want a helper method somewhere which serializes the class to a string...
public static string SerializeToXml<T>(T value)
{
StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer, value);
return writer.ToString();
}
Then just put the string into the db like any other.
The best way to store data in a database is in columns (per property), so that it is queryable and indexable. ORM tools will help with this.
However, it is also possible to serialize a class as a CLOB/BLOB (varchar(max)/varbinary(max) etc).
It this is what you want, avoid anything implementation-specific or version-intolerant; so in particular, don't use BinaryFormatter. Anything contract-based should work; XmlSerializer, DataContractSerializer, etc. Or for fast binary, protobuf-net might be worth a look.
But I stress; columns would be better.
Without generics (better sollution)
public static string SerializeToXml(object value)
{
StringWriter writer = new StringWriter(CultureInfo.InvariantCulture);
XmlSerializer serializer = new XmlSerializer(value.GetType());
serializer.Serialize(writer, value);
return writer.ToString();
}
I've serialized objects as XML and thrown those into the database just fine. Since we knew the max amount of text we used the varchar(max) datatype instead of getting into TEXT or Binary formats.
This was a OLTP web application and one thing we found was that using a column with an xml datatype invoked some significant cpu usage as the xml was validated on every insert. In our case the xml was never queried for anything so not having the xml query capabilities worked out ok for us.
There are couple of options:
Runtime serialization, serializable objects are marked with the
Serializable attribute, in which case the IFormatter class does all the work of
serialization. A serializable object can ISerializable, but then you will
need to implement the GetObjectData( ) method. The problem with runtime serialization is that program reading the xml data needs to have
the knowledge of the CLR types.
Xml serialization: Unline runtime serialization, you will get good interoperability in this case.
The XmlSerializer type contains the methods Serialize( ) and Deserialize( ), thus
any object can be serialized to XML and saved into the database and when you retreive it back, you
can deserialize it easily.
To read data from the database, you can use the SqlCommand class
method that executes SQL queries, namely ExecuteXmlReader( ).
ExecuteXmlReader( ) returns an instance of XmlReader and that will read your xml data.
Check out Linq-to-SQL (questions on SO, resource on MSDN) or other O-R Mapping options.

Categories