Determining which properties to serialize in a class that's passed over a webservice - asp.net

I'm using NHibernate to administer my entities, and to have lazy loading enabled I need to make my properties return an IList<>. Problem is that .NET throws an exception as it can't serialize an interface when I'm trying to pass the entity. This makes perfect sense.
What I need to know is how I can control which fields to serialize, and which not to? My best bet so far is to work around this problem by copying the contents of IList<> into a List<> before serializing the object, but to do that I need to tell .NET that I don't want the IList<> property serialized :)

Just wanted to let you guys know that I found the answer to be the
[System.Xml.Serialization.XmlIgnore] attribute :)

MSDN has an area on Serializing Objects, but what you want is Selective Serialization. So basically, you can mark any property you don't want serialized with the attribute, [NonSerialized]. There is an example in the second link.

Related

How to pass array of custom objects to ASMX webservice?

I am trying to pass an array of custom objects from my asp.net code behind to a webservice method. The webservice is ASMX and I can't change that for now. I can verify up to the point of the code behind calling the webservice, that the custom object is in the array and has the proper values. When I put a break point in the webservice, I notice that the array is null.
I have checked my Service Reference and the collection type is System.array.
I read that I might need to mark my custom class with [DataContract] and the properties as [Datamember] for this to work, but these don't even show up in the intellisense.
I tried all kinds of things and I couldn't get this to work. I tried casting the custom objects as objects and passing them that way. I also tried to cast the whole array as type object and that didn't work. I tried collections; no go. I read a lot on this and couldn't find anyone who could actually do this. So I gave up on doing this with ASMX and tried it with a WCF service. That did work nicely. I created a custom object. I created a strongly typed collection of this class and populated the collection. I then passed this collection to the WCF service and the method was able to see all the objects properly. So if anybody is stuck in the situation I was, try a regular WCF service.

What are the downsides of "typing" your control state?

I am relatively new to Web Parts and Web Forms (I have only worked a lot with the MVC framework).
I am planning to store some data in the control state. All the examples I can find put an object[] array in the control state and the base control state on the 0 index.
I don't really like putting everything in an object[], so I wanted to create an extra class for my web part with typed properties: e.g. MyWebPartControlState. I will store the base control state in a property BaseControlState of type object.
I was wondering if this could cause any problems or if there are any other reasons why this might not be a good idea. I am wondering because it feels logical to me, but I cannot find any examples of control state where they don't put everything in the control state directly or in a object[].
Thanks in advance.
The control state is persisted in the same field as view state and follows the same rules for serialization. All the samples you found use an object array because that's one of the types the optimized state serializer in ASP.NET understands and for which is able to optimize serialization.
If you use a custom object the serializer won't use the optimizations and instead will serialize your object using the BinaryFormatter which will lead to bloated control state. If you want to have a strongly typed view of your state you should implement IStateManager on your custom class so that it encapsulates the transformation of itself from and to simple objects that the serializer understands.
If I recall correctly the serializer can efficiently serialize the following types:
Primitive types (int, long, etc);
DateTime;
string;
Boxed values of supported value types;
Object arrays containing instances of supported types;
Pair and Triplet objects containing instances of supported types.
I wrote a short blogpost illustrating the differences in size resulting from a simple custom class being serialized with BinaryFormatter versus implementing IStateManager and decomposing to simple types that the serializer can optimize. You can find it at:
ASP.NET ViewState Tips and Tricks #2

ASP.NET ScriptService prevent return of null properties in JSON

Basically I want to make my script service only serialise properties that are not null on an array of object I am returning... So this..
{"k":"9wjH38dKw823","s":10,"f":null,"l":null,"j":null,"p":null,"z":null,"i":null,"c":null,"m":0,"t":-1,"u":2}
would be
{"k":"9wjH38dKw823","s":10,"m":0,"t":-1,"u":2}
Does anyone know if this is possible?
Basically the reason for this is because null values are for unchanged properties. A local copy is kept in the javascript that is just updated to reduce traffic to the server. Change values are then merged.
You can create a custom JavaScriptConverter class for the JSON serialization process to use to handle your object, and then put the necessary logic in the Serialize method of that class to exclude the properties that are null.
This article has a clear step-by-step discussion of the process involved in creating it.
You probably would not need to actually implement the Deserialize method (can throw a NotImplementedException) if you are not passing that type of object in as an input parameter to your web services.

Keep a history of values for specific properties of EF entities

I have a requirement to keep a history of values of some fields in an EF4 ASP.NET MVC3 application. This just needs to be a log file of sorts, log the user, datetime, tablename, fieldname, oldvalue, newvalue.
Although it would be pretty easy to code this in various save routines, I'm wondering if I can get global coverage by wiring it into some sort of dataannotation, so that I can perhaps declare
[KeepHistory()]
public string Surname { get; set; }
in my partial class (I'm using POCO but generated from a T4 template).
So Questions
1) Is this a bad idea ? I'm basically proposing to side-effect changes to an entity, not directly referenced by the code, as a result of an annotation.
2) Can it be done ? Will I have access to the right context to tie up with my unit of work so that changes get saved or dropped with the context save?
3) Is there a better way?
4) If you suggest I do this, any pointers would be appreciated - everything I've read is for validation, which may not be the best starting point.
Actually, validation might be a good starting point. Since an attribute does not know about which property or class it was assigned to, but a validation-attribute gets called by the validation framework with all the necessary informátion. If you implement the System.ComponentModel.DataAnnotations.ValidationAttribute class you can override the IsValid(object, ValidationContext) method, which gives you the actual value of the property, the name of the property and the container.
This might take a lot of work, since you need to get to the currently logged-in user etc. I'm guessing that the .NET implementation provides some sort of caching for the specific attributes on an entity type, which would be a pain to implement by yourself.
Another way, would be to use the ObjectStateManager exposed by your EF ObjectContext, which can provide you with the ObjectStateEntry-objects for all entities of a given state. See the
ObjectStateManager.GetObjectStateEntries(EntityState) method, for more information about how to call it (and when). The ObjectStateEntry actually contains a record of the original and current-values, which can be compared to find any changes made within the lifetime of the current ObjectContext.
You might consider using the ObjectStateManager to inject your custom logging behavior, while this behavior decides based on property-attributes which change should be logged.

Why does Flex's ArrayCollection's Contain method look at memory reference?

When using .contains() on an ArrayCollection in Flex, it will always look at the memory reference. It does not appear to look at an .equals() method or .toString() method or anything overridable. Instead, I need to loop through the ArrayCollection every time and check each individual item until I find what I'm looking for.
Does anyone know why Flex/ActionScript was made this way? Why not provide a way from people to use the contains() method the way they want?
Couldn't you just extend ArrayCollection and override the contains() method? Alternatively you can paste the source for ArrayCollection into an "mx/collections" package in your project and modify the source; this "monkey-patching technique" will override the behavior throughout your entire project. However I would be extremely cautious about changing ArrayCollection in that manner: since it's used all over the place in the Flex APIs there is a good chance you'll start breaking other components in the framework.
The contains() method searches by reference, correct (I believe even for primitives), so if you're trying to find a string or an int in an ArrayCollection, you'll have to do the searching yourself, by some variation of looping or searching. I don't think any of us could tell you why there isn't, say, an optional parameter on that method indicating whether to search by ref or by val, though; so it goes, as they say.
But I'd definitely warn you off monkey-patching the framework code -- that's just asking for trouble. :)
Well, it seems like the ArrayCollection doesn't actually look directly at memory, but only as a last resort. It will attempt to find a Unique ID (UID) for the object. If the UID doesn't exist, it will create one for it using the UIDUtil.as.
You can get around this whole default UID stuff by having your object implement the IUID interface and providing your own UID for the object. The ArrayCollection will look at the UID you provide it.
I would suggest a simple:
in_array($haystack, $arrayCollection->toArray());

Resources