please help me understand what's going on in here and whether it should work like that ? I have a generic list of objects from a CMS:
For example List<MyCMS.Articles.Article> myArticles = articles.All
;
Later I output the contents of the list in a JSON format (for CMS UI - table list).
Now a single record would include:
article.Title
article.Alias
article.Guid
article.Description
+
article.SeoProperties.TitleOverride
article.SeoProperties.H1Tag
article.StateProperties.IsActive
article.StateProperties.Channels
etc...
as you can see an Article object has an additional class property - with common properties (used on other object types in the CMS)
I also use a filter class that does some filter operations with LINQ on the collection to return me only articles within a certain channel, for example...
So the problem is that when I serialize the collection as JSON - there are only a few "columns" that I really need to display in my table list, while I have no need in other fields - especially, possibly long fields such as "description" (lazy loaded from file system), etc... - I serialize with DataContractJsonSerializer...
I need a way to control what fields will be included in the JSON result... What I do is I use reflection to set property values to null if I don't need the property and decorate class properties with [DataMember(IsRequired = false, EmitDefaultValue = false)] attributes... - it should work well - but - as soon as I go over (even cloned!!) collection of final objects to strip off the fields = set value to "null" - property value becomes null - application wide - in all collections of such objects... eh ?
Some demo code in here:
void Page_Load() {
MyCms.Content.Games games = new MyCms.Content.Games();
List<MyCms.Content.Games.Game> allGames = games.All;
MyCms.Content.Games games2 = new MyCms.Content.Games();
List<MyCms.Content.Games.Game> allGamesOther = games2.All;
Response.Write("Total games: " + allGames.Count + "<br />");
//This is our fields stripper - with result assigned to a new list
List<MyCms.Content.Games.Game> completelyUnrelatedOtherIsolated_but_notSureList = RemoveUnusedFields(allGamesOther);
List<MyCms.Content.Games.Game> gamesFiltered = allGames.Where(g=>g.GamingProperties.Software=="89070ef9-e115-4907-9996-6421e6013993").ToList();
Response.Write("Filtered games: " + gamesFiltered.Count + "<br /><br />");
}
private List<MyCms.Content.Games.Game> RemoveUnusedFields(List<MyCms.Content.Games.Game> games)
{
List<MyCms.Content.Games.Game> result = new List<MyCms.Content.Games.Game>();
if (games != null && games.Count > 0)
{
//Retrieve a list of current object properties
List<string> myContentProperties = MyCms.Utils.GetContentProperties(games[0]);
MyCms.PropertyReflector pF = new MyCms.PropertyReflector();
foreach (MyCms.Content.Games.Game contentItem in games)
{
MyCms.Content.Games.Game myNewGame = (MyCms.Content.Games.Game)contentItem.Clone();
myNewGame.Images = "wtf!"; //just to be sure we do set this stuff not only null
pF.SetValue(myNewGame, "GamingProperties.Software", ""); //set one property to null for testing
result.Add(myNewGame);
}
}
return result;
}
Objects are set to their "Default values" (basically, null, in most cases) with this:
private object GetDefaultValue(Type type)
{
if (type.IsValueType)
{
try
{
return Activator.CreateInstance(type);
}
catch {
return null;
}
}
return null;
}