Populate null fields in an object through reflection

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite












I have recently implemented this utility class for going through an instance's member fields recursively and assigning them default values if they are null. Here is the implementation in the NullHandler class:



public static class NullHandler

public static void PopulateNullFields<T>(T obj)
BindingFlags.NonPublic);

foreach(var field in fields)

var defaultValue = field.GetValue(obj);

if(defaultValue == null)

defaultValue = GetDefaultValue(field.FieldType);


var subFields = field.FieldType.GetFields(BindingFlags.Instance


public static object GetDefaultValue(Type t)

if(Nullable.GetUnderlyingType(t) != null)

t = Nullable.GetUnderlyingType(t);


if(t == typeof(string))

return "";

else if(t == typeof(DateTime))

return new DateTime();

else if (t.IsValueType)

return Activator.CreateInstance(t);

else if(t.IsArray)

var cinfo = t.GetConstructors().FirstOrDefault(x => x.GetParameters().Count() == 1);

if(cinfo != null)

return cinfo.Invoke(new object 0 );

else

throw new InvalidOperationException("Unable to find array constructor for this array type.");


else if(t.IsEnum)

return Enum.GetValues(t).GetValue(0);

else

var cinfo = t.GetConstructors().Where(x => x.GetParameters().Count() == 0).FirstOrDefault();
if (cinfo != null)

return Activator.CreateInstance(t);

else

throw new InvalidOperationException("No default constructor with no parameter is found for the type.");






The code is currently in use in our XML serialization routine, where we have a requirement for another system that expects an XML file with null values included. The .NET XmlSerializer class omits null properties in the generated XML unless the properties are decorated with the XmlElement(IsNullable = true) attribute.



While we would have rather added the attributes to the model class itself, the model class is (a) created from code-generation, and we would lose the changes if we needed to regenerate the model class, and (b) the generated model class is at least ~3000 LOC, making it time-consuming to manually add the needed attributes ourselves.



Here is a sample of how the NullHandler utility class is in use on our project:



using (var stringWriter = new StringWriter())
using (var xmlStringWriter = XmlWriter.Create(stringWriter, settings))

NullHandler.PopulateNullFields(item.Result.Payee);
serializer.Serialize(xmlStringWriter, item.Result);

// ...save XML to database



I would like to get feedback if there are areas where the code can be improved. I would specifically like to know how I can improve the reusability of the NullHandler class by accounting for any possibly missed cases (most especially in the GetDefaultValues method). Feedback to improve the class's readability would be appreciated as well.







share|improve this question















  • 2




    Fixing the model class generator itself seems cleaner.
    – vnp
    May 1 at 5:36










  • We used the xsd.exe tool from Microsoft to generate the model classes. The XSD file came from a third-party. So we didn't really have the option to modify how the tool generated the model class.
    – InstilledBee
    May 1 at 10:35






  • 1




    Why are you setting private fields instead of public fields and properties? If that doesn't break anything right now, how certain are you that it won't cause problems later, when the generated code needs to be updated?
    – Pieter Witvoet
    May 1 at 20:39










  • Thanks for pointing that out. I have assumed in this case that directly modifying the private fields was appropriate given that xsd.exe created backing fields for the properties anyway. I'll consider this when I go through the code again.
    – InstilledBee
    May 2 at 12:56
















up vote
4
down vote

favorite












I have recently implemented this utility class for going through an instance's member fields recursively and assigning them default values if they are null. Here is the implementation in the NullHandler class:



public static class NullHandler

public static void PopulateNullFields<T>(T obj)
BindingFlags.NonPublic);

foreach(var field in fields)

var defaultValue = field.GetValue(obj);

if(defaultValue == null)

defaultValue = GetDefaultValue(field.FieldType);


var subFields = field.FieldType.GetFields(BindingFlags.Instance


public static object GetDefaultValue(Type t)

if(Nullable.GetUnderlyingType(t) != null)

t = Nullable.GetUnderlyingType(t);


if(t == typeof(string))

return "";

else if(t == typeof(DateTime))

return new DateTime();

else if (t.IsValueType)

return Activator.CreateInstance(t);

else if(t.IsArray)

var cinfo = t.GetConstructors().FirstOrDefault(x => x.GetParameters().Count() == 1);

if(cinfo != null)

return cinfo.Invoke(new object 0 );

else

throw new InvalidOperationException("Unable to find array constructor for this array type.");


else if(t.IsEnum)

return Enum.GetValues(t).GetValue(0);

else

var cinfo = t.GetConstructors().Where(x => x.GetParameters().Count() == 0).FirstOrDefault();
if (cinfo != null)

return Activator.CreateInstance(t);

else

throw new InvalidOperationException("No default constructor with no parameter is found for the type.");






The code is currently in use in our XML serialization routine, where we have a requirement for another system that expects an XML file with null values included. The .NET XmlSerializer class omits null properties in the generated XML unless the properties are decorated with the XmlElement(IsNullable = true) attribute.



While we would have rather added the attributes to the model class itself, the model class is (a) created from code-generation, and we would lose the changes if we needed to regenerate the model class, and (b) the generated model class is at least ~3000 LOC, making it time-consuming to manually add the needed attributes ourselves.



Here is a sample of how the NullHandler utility class is in use on our project:



using (var stringWriter = new StringWriter())
using (var xmlStringWriter = XmlWriter.Create(stringWriter, settings))

NullHandler.PopulateNullFields(item.Result.Payee);
serializer.Serialize(xmlStringWriter, item.Result);

// ...save XML to database



I would like to get feedback if there are areas where the code can be improved. I would specifically like to know how I can improve the reusability of the NullHandler class by accounting for any possibly missed cases (most especially in the GetDefaultValues method). Feedback to improve the class's readability would be appreciated as well.







share|improve this question















  • 2




    Fixing the model class generator itself seems cleaner.
    – vnp
    May 1 at 5:36










  • We used the xsd.exe tool from Microsoft to generate the model classes. The XSD file came from a third-party. So we didn't really have the option to modify how the tool generated the model class.
    – InstilledBee
    May 1 at 10:35






  • 1




    Why are you setting private fields instead of public fields and properties? If that doesn't break anything right now, how certain are you that it won't cause problems later, when the generated code needs to be updated?
    – Pieter Witvoet
    May 1 at 20:39










  • Thanks for pointing that out. I have assumed in this case that directly modifying the private fields was appropriate given that xsd.exe created backing fields for the properties anyway. I'll consider this when I go through the code again.
    – InstilledBee
    May 2 at 12:56












up vote
4
down vote

favorite









up vote
4
down vote

favorite











I have recently implemented this utility class for going through an instance's member fields recursively and assigning them default values if they are null. Here is the implementation in the NullHandler class:



public static class NullHandler

public static void PopulateNullFields<T>(T obj)
BindingFlags.NonPublic);

foreach(var field in fields)

var defaultValue = field.GetValue(obj);

if(defaultValue == null)

defaultValue = GetDefaultValue(field.FieldType);


var subFields = field.FieldType.GetFields(BindingFlags.Instance


public static object GetDefaultValue(Type t)

if(Nullable.GetUnderlyingType(t) != null)

t = Nullable.GetUnderlyingType(t);


if(t == typeof(string))

return "";

else if(t == typeof(DateTime))

return new DateTime();

else if (t.IsValueType)

return Activator.CreateInstance(t);

else if(t.IsArray)

var cinfo = t.GetConstructors().FirstOrDefault(x => x.GetParameters().Count() == 1);

if(cinfo != null)

return cinfo.Invoke(new object 0 );

else

throw new InvalidOperationException("Unable to find array constructor for this array type.");


else if(t.IsEnum)

return Enum.GetValues(t).GetValue(0);

else

var cinfo = t.GetConstructors().Where(x => x.GetParameters().Count() == 0).FirstOrDefault();
if (cinfo != null)

return Activator.CreateInstance(t);

else

throw new InvalidOperationException("No default constructor with no parameter is found for the type.");






The code is currently in use in our XML serialization routine, where we have a requirement for another system that expects an XML file with null values included. The .NET XmlSerializer class omits null properties in the generated XML unless the properties are decorated with the XmlElement(IsNullable = true) attribute.



While we would have rather added the attributes to the model class itself, the model class is (a) created from code-generation, and we would lose the changes if we needed to regenerate the model class, and (b) the generated model class is at least ~3000 LOC, making it time-consuming to manually add the needed attributes ourselves.



Here is a sample of how the NullHandler utility class is in use on our project:



using (var stringWriter = new StringWriter())
using (var xmlStringWriter = XmlWriter.Create(stringWriter, settings))

NullHandler.PopulateNullFields(item.Result.Payee);
serializer.Serialize(xmlStringWriter, item.Result);

// ...save XML to database



I would like to get feedback if there are areas where the code can be improved. I would specifically like to know how I can improve the reusability of the NullHandler class by accounting for any possibly missed cases (most especially in the GetDefaultValues method). Feedback to improve the class's readability would be appreciated as well.







share|improve this question











I have recently implemented this utility class for going through an instance's member fields recursively and assigning them default values if they are null. Here is the implementation in the NullHandler class:



public static class NullHandler

public static void PopulateNullFields<T>(T obj)
BindingFlags.NonPublic);

foreach(var field in fields)

var defaultValue = field.GetValue(obj);

if(defaultValue == null)

defaultValue = GetDefaultValue(field.FieldType);


var subFields = field.FieldType.GetFields(BindingFlags.Instance


public static object GetDefaultValue(Type t)

if(Nullable.GetUnderlyingType(t) != null)

t = Nullable.GetUnderlyingType(t);


if(t == typeof(string))

return "";

else if(t == typeof(DateTime))

return new DateTime();

else if (t.IsValueType)

return Activator.CreateInstance(t);

else if(t.IsArray)

var cinfo = t.GetConstructors().FirstOrDefault(x => x.GetParameters().Count() == 1);

if(cinfo != null)

return cinfo.Invoke(new object 0 );

else

throw new InvalidOperationException("Unable to find array constructor for this array type.");


else if(t.IsEnum)

return Enum.GetValues(t).GetValue(0);

else

var cinfo = t.GetConstructors().Where(x => x.GetParameters().Count() == 0).FirstOrDefault();
if (cinfo != null)

return Activator.CreateInstance(t);

else

throw new InvalidOperationException("No default constructor with no parameter is found for the type.");






The code is currently in use in our XML serialization routine, where we have a requirement for another system that expects an XML file with null values included. The .NET XmlSerializer class omits null properties in the generated XML unless the properties are decorated with the XmlElement(IsNullable = true) attribute.



While we would have rather added the attributes to the model class itself, the model class is (a) created from code-generation, and we would lose the changes if we needed to regenerate the model class, and (b) the generated model class is at least ~3000 LOC, making it time-consuming to manually add the needed attributes ourselves.



Here is a sample of how the NullHandler utility class is in use on our project:



using (var stringWriter = new StringWriter())
using (var xmlStringWriter = XmlWriter.Create(stringWriter, settings))

NullHandler.PopulateNullFields(item.Result.Payee);
serializer.Serialize(xmlStringWriter, item.Result);

// ...save XML to database



I would like to get feedback if there are areas where the code can be improved. I would specifically like to know how I can improve the reusability of the NullHandler class by accounting for any possibly missed cases (most especially in the GetDefaultValues method). Feedback to improve the class's readability would be appreciated as well.









share|improve this question










share|improve this question




share|improve this question









asked May 1 at 3:48









InstilledBee

235




235







  • 2




    Fixing the model class generator itself seems cleaner.
    – vnp
    May 1 at 5:36










  • We used the xsd.exe tool from Microsoft to generate the model classes. The XSD file came from a third-party. So we didn't really have the option to modify how the tool generated the model class.
    – InstilledBee
    May 1 at 10:35






  • 1




    Why are you setting private fields instead of public fields and properties? If that doesn't break anything right now, how certain are you that it won't cause problems later, when the generated code needs to be updated?
    – Pieter Witvoet
    May 1 at 20:39










  • Thanks for pointing that out. I have assumed in this case that directly modifying the private fields was appropriate given that xsd.exe created backing fields for the properties anyway. I'll consider this when I go through the code again.
    – InstilledBee
    May 2 at 12:56












  • 2




    Fixing the model class generator itself seems cleaner.
    – vnp
    May 1 at 5:36










  • We used the xsd.exe tool from Microsoft to generate the model classes. The XSD file came from a third-party. So we didn't really have the option to modify how the tool generated the model class.
    – InstilledBee
    May 1 at 10:35






  • 1




    Why are you setting private fields instead of public fields and properties? If that doesn't break anything right now, how certain are you that it won't cause problems later, when the generated code needs to be updated?
    – Pieter Witvoet
    May 1 at 20:39










  • Thanks for pointing that out. I have assumed in this case that directly modifying the private fields was appropriate given that xsd.exe created backing fields for the properties anyway. I'll consider this when I go through the code again.
    – InstilledBee
    May 2 at 12:56







2




2




Fixing the model class generator itself seems cleaner.
– vnp
May 1 at 5:36




Fixing the model class generator itself seems cleaner.
– vnp
May 1 at 5:36












We used the xsd.exe tool from Microsoft to generate the model classes. The XSD file came from a third-party. So we didn't really have the option to modify how the tool generated the model class.
– InstilledBee
May 1 at 10:35




We used the xsd.exe tool from Microsoft to generate the model classes. The XSD file came from a third-party. So we didn't really have the option to modify how the tool generated the model class.
– InstilledBee
May 1 at 10:35




1




1




Why are you setting private fields instead of public fields and properties? If that doesn't break anything right now, how certain are you that it won't cause problems later, when the generated code needs to be updated?
– Pieter Witvoet
May 1 at 20:39




Why are you setting private fields instead of public fields and properties? If that doesn't break anything right now, how certain are you that it won't cause problems later, when the generated code needs to be updated?
– Pieter Witvoet
May 1 at 20:39












Thanks for pointing that out. I have assumed in this case that directly modifying the private fields was appropriate given that xsd.exe created backing fields for the properties anyway. I'll consider this when I go through the code again.
– InstilledBee
May 2 at 12:56




Thanks for pointing that out. I have assumed in this case that directly modifying the private fields was appropriate given that xsd.exe created backing fields for the properties anyway. I'll consider this when I go through the code again.
– InstilledBee
May 2 at 12:56










2 Answers
2






active

oldest

votes

















up vote
2
down vote



accepted










You can replace some parts (like enums, value types, or date-time) of the GetDefaultValue method with Expression.Default which




Represents the default value of a type or an empty expression.




This means that if you wanted to get the default value for DateTime you could use Expression.Default to generate this code for you: (object)default(DateTime).



And it goes like that:



var type = typeof(DateTime);

// (object)default(type)
var getDefaultValue =
Expression.Lambda<Func<object>>(
// it needs to be casted to `object` to create `Func<object>`
Expression.Convert(
Expression.Default(type),
typeof(object)
)
).Compile();

getDefaultValue().Dump(); // 01/01/0001 00:00:00


Just make sure to cache the generated Func<object> for each Type because Compile takes some time and it will otherwise become the bottleneck of your utility.





"No default constructor with no parameter is found for the type.";




A default constructor is a parameterless one so it's not necessary to repeat it.






share|improve this answer





















  • Accepting this answer because this was the one that provided direct feedback on the code I posted and how it could be improved. Thanks.
    – InstilledBee
    May 3 at 12:31

















up vote
3
down vote













A different option is to fix this at the creation of the XmlSerializer. The XmlSerializer constructor can take a parameter for XmlAttributeOverrides



You could create a method to auto add the XmlElementAttribute, if missing, or set the IsNullable to true.



public static XmlAttributeOverrides AddIsNullableTrue(Type type)
p.PropertyType == typeof (string)))

var xmlAttributes = new XmlAttributes();
var attr = prop.GetCustomAttribute<XmlElementAttribute>();
if (attr != null)

attr.IsNullable = true;

else

attr = new XmlElementAttribute() IsNullable = true;

xmlAttributes.XmlElements.Add(attr);
xmlOverrides.Add(type, prop.Name, xmlAttributes);

return xmlOverrides;



Now when you create your XmlSerializer you just need to pass in the XmlAttributeOverrides



XmlSerializer SerializerObj = new XmlSerializer(typeof(TestClass), AddIsNullableTrue(typeof(TestClass)));


This example is assuming the class is called TestClass. Now you don't need to populate null fields and fields will be output to XML that are null.






share|improve this answer























  • I wasn't able to find out about XmlAttributeOverrides when initially searching for strategies to our problem. The solution I posted was the one I quickly thought of given a quick deadline on the task as well. Thanks for posting a cleaner solution.
    – InstilledBee
    May 3 at 12:35










Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193322%2fpopulate-null-fields-in-an-object-through-reflection%23new-answer', 'question_page');

);

Post as a guest






























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










You can replace some parts (like enums, value types, or date-time) of the GetDefaultValue method with Expression.Default which




Represents the default value of a type or an empty expression.




This means that if you wanted to get the default value for DateTime you could use Expression.Default to generate this code for you: (object)default(DateTime).



And it goes like that:



var type = typeof(DateTime);

// (object)default(type)
var getDefaultValue =
Expression.Lambda<Func<object>>(
// it needs to be casted to `object` to create `Func<object>`
Expression.Convert(
Expression.Default(type),
typeof(object)
)
).Compile();

getDefaultValue().Dump(); // 01/01/0001 00:00:00


Just make sure to cache the generated Func<object> for each Type because Compile takes some time and it will otherwise become the bottleneck of your utility.





"No default constructor with no parameter is found for the type.";




A default constructor is a parameterless one so it's not necessary to repeat it.






share|improve this answer





















  • Accepting this answer because this was the one that provided direct feedback on the code I posted and how it could be improved. Thanks.
    – InstilledBee
    May 3 at 12:31














up vote
2
down vote



accepted










You can replace some parts (like enums, value types, or date-time) of the GetDefaultValue method with Expression.Default which




Represents the default value of a type or an empty expression.




This means that if you wanted to get the default value for DateTime you could use Expression.Default to generate this code for you: (object)default(DateTime).



And it goes like that:



var type = typeof(DateTime);

// (object)default(type)
var getDefaultValue =
Expression.Lambda<Func<object>>(
// it needs to be casted to `object` to create `Func<object>`
Expression.Convert(
Expression.Default(type),
typeof(object)
)
).Compile();

getDefaultValue().Dump(); // 01/01/0001 00:00:00


Just make sure to cache the generated Func<object> for each Type because Compile takes some time and it will otherwise become the bottleneck of your utility.





"No default constructor with no parameter is found for the type.";




A default constructor is a parameterless one so it's not necessary to repeat it.






share|improve this answer





















  • Accepting this answer because this was the one that provided direct feedback on the code I posted and how it could be improved. Thanks.
    – InstilledBee
    May 3 at 12:31












up vote
2
down vote



accepted







up vote
2
down vote



accepted






You can replace some parts (like enums, value types, or date-time) of the GetDefaultValue method with Expression.Default which




Represents the default value of a type or an empty expression.




This means that if you wanted to get the default value for DateTime you could use Expression.Default to generate this code for you: (object)default(DateTime).



And it goes like that:



var type = typeof(DateTime);

// (object)default(type)
var getDefaultValue =
Expression.Lambda<Func<object>>(
// it needs to be casted to `object` to create `Func<object>`
Expression.Convert(
Expression.Default(type),
typeof(object)
)
).Compile();

getDefaultValue().Dump(); // 01/01/0001 00:00:00


Just make sure to cache the generated Func<object> for each Type because Compile takes some time and it will otherwise become the bottleneck of your utility.





"No default constructor with no parameter is found for the type.";




A default constructor is a parameterless one so it's not necessary to repeat it.






share|improve this answer













You can replace some parts (like enums, value types, or date-time) of the GetDefaultValue method with Expression.Default which




Represents the default value of a type or an empty expression.




This means that if you wanted to get the default value for DateTime you could use Expression.Default to generate this code for you: (object)default(DateTime).



And it goes like that:



var type = typeof(DateTime);

// (object)default(type)
var getDefaultValue =
Expression.Lambda<Func<object>>(
// it needs to be casted to `object` to create `Func<object>`
Expression.Convert(
Expression.Default(type),
typeof(object)
)
).Compile();

getDefaultValue().Dump(); // 01/01/0001 00:00:00


Just make sure to cache the generated Func<object> for each Type because Compile takes some time and it will otherwise become the bottleneck of your utility.





"No default constructor with no parameter is found for the type.";




A default constructor is a parameterless one so it's not necessary to repeat it.







share|improve this answer













share|improve this answer



share|improve this answer











answered May 1 at 17:22









t3chb0t

32k54195




32k54195











  • Accepting this answer because this was the one that provided direct feedback on the code I posted and how it could be improved. Thanks.
    – InstilledBee
    May 3 at 12:31
















  • Accepting this answer because this was the one that provided direct feedback on the code I posted and how it could be improved. Thanks.
    – InstilledBee
    May 3 at 12:31















Accepting this answer because this was the one that provided direct feedback on the code I posted and how it could be improved. Thanks.
– InstilledBee
May 3 at 12:31




Accepting this answer because this was the one that provided direct feedback on the code I posted and how it could be improved. Thanks.
– InstilledBee
May 3 at 12:31












up vote
3
down vote













A different option is to fix this at the creation of the XmlSerializer. The XmlSerializer constructor can take a parameter for XmlAttributeOverrides



You could create a method to auto add the XmlElementAttribute, if missing, or set the IsNullable to true.



public static XmlAttributeOverrides AddIsNullableTrue(Type type)
p.PropertyType == typeof (string)))

var xmlAttributes = new XmlAttributes();
var attr = prop.GetCustomAttribute<XmlElementAttribute>();
if (attr != null)

attr.IsNullable = true;

else

attr = new XmlElementAttribute() IsNullable = true;

xmlAttributes.XmlElements.Add(attr);
xmlOverrides.Add(type, prop.Name, xmlAttributes);

return xmlOverrides;



Now when you create your XmlSerializer you just need to pass in the XmlAttributeOverrides



XmlSerializer SerializerObj = new XmlSerializer(typeof(TestClass), AddIsNullableTrue(typeof(TestClass)));


This example is assuming the class is called TestClass. Now you don't need to populate null fields and fields will be output to XML that are null.






share|improve this answer























  • I wasn't able to find out about XmlAttributeOverrides when initially searching for strategies to our problem. The solution I posted was the one I quickly thought of given a quick deadline on the task as well. Thanks for posting a cleaner solution.
    – InstilledBee
    May 3 at 12:35














up vote
3
down vote













A different option is to fix this at the creation of the XmlSerializer. The XmlSerializer constructor can take a parameter for XmlAttributeOverrides



You could create a method to auto add the XmlElementAttribute, if missing, or set the IsNullable to true.



public static XmlAttributeOverrides AddIsNullableTrue(Type type)
p.PropertyType == typeof (string)))

var xmlAttributes = new XmlAttributes();
var attr = prop.GetCustomAttribute<XmlElementAttribute>();
if (attr != null)

attr.IsNullable = true;

else

attr = new XmlElementAttribute() IsNullable = true;

xmlAttributes.XmlElements.Add(attr);
xmlOverrides.Add(type, prop.Name, xmlAttributes);

return xmlOverrides;



Now when you create your XmlSerializer you just need to pass in the XmlAttributeOverrides



XmlSerializer SerializerObj = new XmlSerializer(typeof(TestClass), AddIsNullableTrue(typeof(TestClass)));


This example is assuming the class is called TestClass. Now you don't need to populate null fields and fields will be output to XML that are null.






share|improve this answer























  • I wasn't able to find out about XmlAttributeOverrides when initially searching for strategies to our problem. The solution I posted was the one I quickly thought of given a quick deadline on the task as well. Thanks for posting a cleaner solution.
    – InstilledBee
    May 3 at 12:35












up vote
3
down vote










up vote
3
down vote









A different option is to fix this at the creation of the XmlSerializer. The XmlSerializer constructor can take a parameter for XmlAttributeOverrides



You could create a method to auto add the XmlElementAttribute, if missing, or set the IsNullable to true.



public static XmlAttributeOverrides AddIsNullableTrue(Type type)
p.PropertyType == typeof (string)))

var xmlAttributes = new XmlAttributes();
var attr = prop.GetCustomAttribute<XmlElementAttribute>();
if (attr != null)

attr.IsNullable = true;

else

attr = new XmlElementAttribute() IsNullable = true;

xmlAttributes.XmlElements.Add(attr);
xmlOverrides.Add(type, prop.Name, xmlAttributes);

return xmlOverrides;



Now when you create your XmlSerializer you just need to pass in the XmlAttributeOverrides



XmlSerializer SerializerObj = new XmlSerializer(typeof(TestClass), AddIsNullableTrue(typeof(TestClass)));


This example is assuming the class is called TestClass. Now you don't need to populate null fields and fields will be output to XML that are null.






share|improve this answer















A different option is to fix this at the creation of the XmlSerializer. The XmlSerializer constructor can take a parameter for XmlAttributeOverrides



You could create a method to auto add the XmlElementAttribute, if missing, or set the IsNullable to true.



public static XmlAttributeOverrides AddIsNullableTrue(Type type)
p.PropertyType == typeof (string)))

var xmlAttributes = new XmlAttributes();
var attr = prop.GetCustomAttribute<XmlElementAttribute>();
if (attr != null)

attr.IsNullable = true;

else

attr = new XmlElementAttribute() IsNullable = true;

xmlAttributes.XmlElements.Add(attr);
xmlOverrides.Add(type, prop.Name, xmlAttributes);

return xmlOverrides;



Now when you create your XmlSerializer you just need to pass in the XmlAttributeOverrides



XmlSerializer SerializerObj = new XmlSerializer(typeof(TestClass), AddIsNullableTrue(typeof(TestClass)));


This example is assuming the class is called TestClass. Now you don't need to populate null fields and fields will be output to XML that are null.







share|improve this answer















share|improve this answer



share|improve this answer








edited May 2 at 15:41


























answered May 1 at 16:49









CharlesNRice

1,601311




1,601311











  • I wasn't able to find out about XmlAttributeOverrides when initially searching for strategies to our problem. The solution I posted was the one I quickly thought of given a quick deadline on the task as well. Thanks for posting a cleaner solution.
    – InstilledBee
    May 3 at 12:35
















  • I wasn't able to find out about XmlAttributeOverrides when initially searching for strategies to our problem. The solution I posted was the one I quickly thought of given a quick deadline on the task as well. Thanks for posting a cleaner solution.
    – InstilledBee
    May 3 at 12:35















I wasn't able to find out about XmlAttributeOverrides when initially searching for strategies to our problem. The solution I posted was the one I quickly thought of given a quick deadline on the task as well. Thanks for posting a cleaner solution.
– InstilledBee
May 3 at 12:35




I wasn't able to find out about XmlAttributeOverrides when initially searching for strategies to our problem. The solution I posted was the one I quickly thought of given a quick deadline on the task as well. Thanks for posting a cleaner solution.
– InstilledBee
May 3 at 12:35












 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193322%2fpopulate-null-fields-in-an-object-through-reflection%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Chat program with C++ and SFML

Function to Return a JSON Like Objects Using VBA Collections and Arrays

Will my employers contract hold up in court?