I am trying to implement selective serialization at runtime. So for example my controller method populates a list of objects but my caller only wants 3 or 4 properties from those objects, whilst another caller may want 10 properties. So I want to control
the serialization.
I have looked at GetObjectData but my current implementation is way too slow - basically every object checks its properties using Reflection, checks those against the ok list (AppSettings per object i.e. ProductDefault, "Id,Name,Description,Price") and does
an info.Add(fieldname,value). This is massively slow - maybe because I haven't implemented this in the best way. Any ideas? I am currently using a JSON.NET formatter but I would rather not do anything with the formatter because if the caller wants XML output
all of a sudden then I have to implement some change to that formatter too. Which is why I am looking just at the GetObjectData method and the Iserializable interface because then it won't matter what format they want it in.
The caller uses a URL which specifies a known AppSettings field list which limits the output.
How best to use this info? Currently I create each object with that string value passed in (a property of the object) so when it comes to GetObjectData it is available to me to test. I am not sure if or where I can add info to StreamingContext that might
help me, Is this from the formatter and if so, how? Again, if it is then it is not ideal because I want to avoid doing it for specific formatters.
I can probably just access the Request and check the AppSettings value passed there but I still think the problem is the length of time to do all the processing of that field list - any ideas for the fastest solution?
I had planned on it being part of the REST URL. It would be one of some preset values. So lets say our callerA would use SetA in its URL to indicate using the SetA group of properties. If they wanted to change that set then they would notify us and we would
just change the configuration so that suddenly their output is changed - their call remains the same.
callerB would be using their own URL.
A URL without that parameter would use the full set of properties.
To do this I use PropertyInfo (which I get using System.Reflection) and loop through checking each property against my list (which I read using AppSettingsReader). Obviously I am doing this for each object. I should probably be able to get this PropertyInfo
from the SerializationInfo parameter? But I then use the string in the AppSettings, split it into a List<string> then loop through PropertyInfo and check whether it is in the list (or if the list is empty).
To add complication I did try increasing the complexity so that there could also be a limit on the fields a specific user was allowed to see AND also the possibility of defining an EXCLUDE list in the case of no specific properties (therefore the full set).
Againboth of these were in AppSettings which I processed into List<string> and then used the Intersect function to get a final list.
Without using GetObjectData I can return 1MB of info in a fraction of a second. Using it with my (possibly less than optimized code!) results in many seconds (30+)
Any suggestions for improvement greatly appreciated. I'm sure this is not the best way and in fact it may be that we just end up deciding that the cost of doing this restriction is jus too great.
phancey1
Member
16 Points
16 Posts
Web API output
Mar 23, 2012 05:51 PM|LINK
hi,
I am trying to implement selective serialization at runtime. So for example my controller method populates a list of objects but my caller only wants 3 or 4 properties from those objects, whilst another caller may want 10 properties. So I want to control the serialization.
I have looked at GetObjectData but my current implementation is way too slow - basically every object checks its properties using Reflection, checks those against the ok list (AppSettings per object i.e. ProductDefault, "Id,Name,Description,Price") and does an info.Add(fieldname,value). This is massively slow - maybe because I haven't implemented this in the best way. Any ideas? I am currently using a JSON.NET formatter but I would rather not do anything with the formatter because if the caller wants XML output all of a sudden then I have to implement some change to that formatter too. Which is why I am looking just at the GetObjectData method and the Iserializable interface because then it won't matter what format they want it in.
The caller uses a URL which specifies a known AppSettings field list which limits the output.
How best to use this info? Currently I create each object with that string value passed in (a property of the object) so when it comes to GetObjectData it is available to me to test. I am not sure if or where I can add info to StreamingContext that might help me, Is this from the formatter and if so, how? Again, if it is then it is not ideal because I want to avoid doing it for specific formatters.
I can probably just access the Request and check the AppSettings value passed there but I still think the problem is the length of time to do all the processing of that field list - any ideas for the fastest solution?
thanks very much
P
raghuramn
Member
248 Points
64 Posts
Microsoft
Re: Web API output
Mar 23, 2012 09:55 PM|LINK
how does the caller specify what properties it wants ?
phancey1
Member
16 Points
16 Posts
Re: Web API output
Mar 23, 2012 10:17 PM|LINK
I had planned on it being part of the REST URL. It would be one of some preset values. So lets say our callerA would use SetA in its URL to indicate using the SetA group of properties. If they wanted to change that set then they would notify us and we would just change the configuration so that suddenly their output is changed - their call remains the same.
callerB would be using their own URL.
A URL without that parameter would use the full set of properties.
To do this I use PropertyInfo (which I get using System.Reflection) and loop through checking each property against my list (which I read using AppSettingsReader). Obviously I am doing this for each object. I should probably be able to get this PropertyInfo from the SerializationInfo parameter? But I then use the string in the AppSettings, split it into a List<string> then loop through PropertyInfo and check whether it is in the list (or if the list is empty).
To add complication I did try increasing the complexity so that there could also be a limit on the fields a specific user was allowed to see AND also the possibility of defining an EXCLUDE list in the case of no specific properties (therefore the full set). Againboth of these were in AppSettings which I processed into List<string> and then used the Intersect function to get a final list.
Without using GetObjectData I can return 1MB of info in a fraction of a second. Using it with my (possibly less than optimized code!) results in many seconds (30+)
Any suggestions for improvement greatly appreciated. I'm sure this is not the best way and in fact it may be that we just end up deciding that the cost of doing this restriction is jus too great.
thanks for your time.
phancey1
Member
16 Points
16 Posts
Re: Web API output
Mar 26, 2012 06:52 PM|LINK
ok, well if I cache the AppSettings it isn't too bad. It's the AppSettings reader that eats up the time.
just in case anyone else needs a quick answer to this.