XML Serialization to use empty array instead of NULL - c#

I have a property
[XmlElement]
public string[] Emails { get; set; }
which is initialized as string[0] at constructor.
If I XML serialize and deserialize a default instance of this object, the property is NULL.
How can I tell the XML Serializer to use an empty array instead of NULL for this property?

5 years later... :)
Replacing Array with List<> did the trick for me.
[XmlElement (IsNullable = false)]
public List<string> Emails {get;set;}

Related

Deserializing JSON string with JavaScriptSerializer to return a single dynamic object instead of an array of keys and values

Consider the following JSON string in C#:
{
"BuyerRegion":"BuyerRegion [0][27]",
"SellerRegion":"SellerRegion [0][29]",
"HubRegion":"HubRegion [0][31]",
"PartNo":"TINT_MNUM [0][3]",
"BuyerCompID":"BuyerCompId [0][28]",
"SellerCompId":"SellerCompId [0][30]",
"HubCompId":"HubCompId [0][32]"
}
I then tried to Deserialize the string into a dynamic object in C# using:
object obj = new JavaScriptSerializer().Deserialize<object>(s); //where s contains the JSON string
However, the returning obj is an array of key/value pairs:
Any idea how I can have them deserialized into one single dynamic object where I can access the properties using:
obj.BuyerRegion //returns "BuyerRegion [0][27]"
JsonConvert/NewtonSoft isn't a choice.
You can use instead of object some ModelDto and cast to it, I mean:
public class ModelDto {
public string Key {get;set;}
public string Value {get;set;}
}
Or you can use follwoing code to take value from dictionary by key:
string buyerRegion = dict["BuyerRegion"];
Or you can use ExpandoObject as suggested in a comments to your question.
After trying several methods, I came to realize that accessing the properties is as easy as calling:
obj["BuyerRegion"]

How to ignore null array elements with Newtonsoft JSON serializer

I'm attempting to serialize an object array, but I need it to ignore null elements. I realize I could simply have logic upon deserialization that checks for the nulls, however I don't want to write unnecessary data over the network. The array can have a maximum of 9 elements, but all 9 indices are not used in every instance. I understand that a list could be utilized, but for efficiency sake I do not wish to do that.
Per similar questions I've browsed on this site, I've attempted to add the following tag to the array: [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
However, this approach does not ignore null elements.
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Node[] Nodes { get; }
public void Init()
{
Nodes = new Node[9];
}
public string Encode()
{
return JsonConvert.SerializeObject(Nodes, Formatting.None);
}
Is there an elegant solution to this?
The simplest solution is just to filter the array just before you serialize it. You can do this in your Encode method, without instantiating a new array:
public string Encode()
{
return JsonConvert.SerializeObject(Nodes.Where(n => n != null), Formatting.None);
}
Fiddle: https://dotnetfiddle.net/dj8lnP
If you don't like that idea, for whatever reason, you can use a custom JsonConverter similar to the one in Excluding specific items in a collection when serializing to JSON to do the filtering.

Serialize a list of derived list [duplicate]

This question already has answers here:
How do I get json.net to serialize members of a class deriving from List<T>?
(3 answers)
Closed 6 years ago.
I can't find a way to serialize with JSON.NET a list of derived lists, and I'm starting to wonder if it's even possible. Let me explain the situation with some code.
I've created a new class which is derived from a list of a specific object (tried first with a generic one) and added a string property NomGroupe:
public class GroupeActes : List<Acte>
{
public string NomGroupe { get; set; }
public GroupeActes(string nom, List<Acte> liste)
{
NomGroupe = nom;
foreach (var acte in liste)
{
this.Add(acte);
}
}
}
Then, in my code, I've declared a list of this class (List<GroupeActes> listOfGroupeActes) and I fill it with data. For the serialization, I use this code:
JsonSerializer serializer = new JsonSerializer();
serializer.TypeNameHandling = TypeNameHandling.All;
using (StreamWriter sw = new StreamWriter(#"listOfGroupeActes.json"))
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, listOfGroupeActes);
}
I've tried with and without the TypeNameHandling.All parameter and with several combination of Json.net properties and even with DataContract/DataMember.
So far, I only managed to get in my json file either the data of each nested List<Acte> without the NomGroupe property, or the other way around. But not both, which is what I'd like to have.
Two questions then:
Is it even possible?
If yes, how can I do it?
Thanks for your help!
You don't want to inherit from List<T>.
Create a list property instead:
public class GroupeActes
{
public List<Acte> Actes { get; set; }
public string NomGroupe { get; set; }
public GroupeActes(string nom, List<Acte> liste)
{
NomGroupe = nom;
Actes.AddRange(acte);
}
}
Lists (and other collection types) get special treatment while serializing. You don't want the collection type's public properties (such as Capacity and Count) in your output, so the property you added through inheritance won't be serialized either.
A collection is serialized like this:
if o is IEnumerable
foreach object s in o
serialize o
So the serializer won't even look at your enumerable's properties.
Try to use Newtonsoft Json.NET
string itemToSend = JsonConvert.SerializeObject(dataModel);

Prevent timezone conversion on deserialization of List<DateTime> Collection

I have a class which I use the XmlSerializer with to serialize data to and from XML files.
I have several DateTime properties. In the post, Prevent timezone conversion on deserialization of DateTime value the answer correctly removes timezone offsets from DateTime properties.
However, I have a property which is a list of DateTime objects that I can't remove the timezones from.
[XmlElement]
public List<DateTime> Times {get; set;}
I have tired something like this, but the value is always null and none of the data is correctly serialized to the list property.
[XmlIgnore]
public List<DateTime> Times {get; set;}
[XmlElement(ElementName = "Times")]
public List<string> TimesString
{
get
{
return Times.ForEach(fe => RemoveTimeZone(fe));
}
set
{
foreach(var v in value)
{
Times.Add(ConvertToDate(v));
}
}
}
The value property is always empty and both list properties are always empty.
My goal is to not create a new class, but to somehow bind directly to my list properties.
Your TimesString property is a proxy collection property, i.e. a property that gets or sets an underlying collection, transforming its members in the process. The simplest way to make such a proxy collection work correctly with XmlSerializer is to make it be an array rather than a list, in your case a string []:
[XmlIgnore]
public List<DateTime> Times { get; set; }
[XmlElement(ElementName = "Times")]
public string [] TimesString
{
get
{
return Times == null ? null : Times.Select(t => RemoveTimeZone(t)).ToArray();
}
set
{
if (value == null)
return;
(Times = Times ?? new List<DateTime>(value.Length)).AddRange(value.Select(s => ConvertToDate(s)));
}
}
string [] works while List<string> does not because XmlSerializer deserializes a property referring to a class implementing IList<T> in the following way:
It calls the getter to get the list. If null, it allocates a list and sets it via the setter. It holds onto the list in some local variable while populating it.
It deserializes each list element, and adds it to the list it is holding.
And that's it. It never calls the containing class's list property setter afterwards.
However, since an array is basically a read-only collection and so cannot be added to once allocated, it cannot be set back until completely populated. This is what XmlSerializer does, which allows proxy array properties to deserialized successfully.
For more, see Cannot deserialize XML into a list using XML Deserializer or XML Deserialization of collection property with code defaults.

Serialize T that contains List<T>

I want to serialize a MyClass, which is a class that contains a list MyClass.
In the XML, I want to write only myClass.Name, then when I deserialize it, I then find which MyClass should be in which other MyClass. I have the following code that properly serializes the list of MyClass into a list of string. However, it doesn't deserialize the list of string.
//List of actual object. It's what I use when I work with the object.
[XmlIgnore]
public List<TaskConfiguration> ChildTasks { get; set; }
//Used by the serializer to get the string list, and used
//by the serializer to deserialize the string list to.
[XmlArray("ChildTasks")]
public List<string> ChildTasksSurrogate
{
get
{
List<string> childTaskList = new List<string>();
if (ChildTasks != null)
childTaskList.AddRange(ChildTasks.Select(ct => ct.Name).ToList());
if (_childTasksSurrogate != null)
childTaskList.AddRange(_childTasksSurrogate);
//Clears it not to use it when it serializes.
_childTasksSurrogate = null;
return childTaskList;
}
set
{
_childTasksSurrogate = value;
}
}
[XmlIgnore]
private List<string> _childTasksSurrogate;
As I said, the serialization works. The problem lies with the deserialization. After the deserialization, MyClass._childTasksSurrogate is null.
The problem was related to HOW does the XmlSerializer deserializes the Xml :
I thought that the XmlSerializer would assign the whole property (read: myList = DeserializedList), while it looks like it adds all the elements (read: myList.AddRange(DeserializedList).

Categories

Resources