Reputation: 43214
Given such object:
Foo foo = new Foo
{
A = "a",
B = "b",
C = "c",
D = "d"
};
How can I serialize and deserialize only certain properties (e.g. A and D).
Original:
{ A = "a", B = "b", C = "c", D = "d" }
Serialized:
{ A = "a", D = "d" }
Deserialized:
{ A = "a", B = null, C = null, D = "d" }
I have wrote some code using JavaScriptSerializer from System.Web.Extensions.dll:
public string Serialize<T>(T obj, Func<T, object> filter)
{
return new JavaScriptSerializer().Serialize(filter(obj));
}
public T Deserialize<T>(string input)
{
return new JavaScriptSerializer().Deserialize<T>(input);
}
void Test()
{
var filter = new Func<Foo, object>(o => new { o.A, o.D });
string serialized = Serialize(foo, filter);
// {"A":"a","D":"d"}
Foo deserialized = Deserialize<Foo>(serialized);
// { A = "a", B = null, C = null, D = "d" }
}
But I would like the deserializer to work a bit differently:
Foo output = new Foo
{
A = "1",
B = "2",
C = "3",
D = "4"
};
Deserialize(output, serialized);
// { A = "a", B = "2", C = "3", D = "d" }
Any ideas?
Also, may be there are some better or existing alternatives available?
EDIT:
There was some suggestions to use attributes to specify serializable fields. I am looking for more dynamic solution. So I can serialize A, B and the next time C, D.
EDIT 2:
Any serialization solutions (JSON, XML, Binary, Yaml, ...) are fine.
Upvotes: 5
Views: 10699
Reputation: 3434
What about the [NonSerialized()]
attribute tag?
class Foo
{
field A;
[NonSerialized()]
field B;
[NonSerialized()]
field C;
field D;
}
Upvotes: 1
Reputation: 15673
Pretty easy--just decorate the methods you wish to ignore with the [ScriptIgnore]
attribute.
Upvotes: 24
Reputation: 66
I have done something similar myself with the Javascript Serializer in the past. In my case I only wanted to serialize nullable properties in the object that contained a value. I did this by using reflection, checking the property for a value and adding the property to a Dictionary e.g.
public static Dictionary<string,object> CollectFilledProperties(object instance)
{
Dictionary<string,object> filledProperties = new Dictionary<string,object>();
object data = null;
PropertyInfo[] properties = instance.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
data = property.GetValue(instance, null);
if (IsNullable(property.PropertyType) && data == null)
{
// Nullable fields without a value i.e. (still null) are ignored.
continue;
}
// Filled has data.
filledProperties[property.Name] = data;
}
return filledProperties;
}
public static bool IsNullable(Type checkType)
{
if (checkType.IsGenericType && checkType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// We are a nullable type - yipee.
return true;
}
return false;
}
Then instead of serializing the original object you pass the dictionary and bob's your uncle.
Upvotes: 5
Reputation: 1635
There are attributes that can be applied to classes and/or properties that control serialization. Attributes that control serialization.
Upvotes: 3