Serialized objects in view state - asp.net

Hi i have been going through the documentation of viewstate. http://msdn.microsoft.com/en-us/library/ms227551(v=VS.85).aspx It was mentioned that objects that can be serialized are stored in viewstate. What is the meaning of serializing of objects ??

Serialization is the process of turning an object into a stream of bytes that can be stored somewhere or sent across the wire.
Specifically in .NET, you can make a class serializable by adding the [Serializable] (C#) or <Serializable> (VB) attribute to the class declaration.

Serialization is the process of taking an object in it's current state and turning into a "data" representation, most commonly in binary or xml formats.
For more information check out:
http://en.wikipedia.org/wiki/Serialization

Related

Are properties within a Serializable class automatically serialized when inserted on Session object in ASP.NET?

I have an ASP.NET application which uses InProc session state mode. I have a class marked as serializable:
namespace MyNamespace
{
[Serializable]
public class MyClass
{
public System.Web.Mvc.SelectList myList { get; set; }
}
}
...Now I have a doubt: When assigning the property value within the serialized class to the session object like below:
Session["MyList"] = InstaceOfMyClass.myList;
... is myList property automatically serialized once inserted to Session["MyList"] object?
In case it is not serialized, how can I serialize it on inserting to Session["MyList"] object? by indicate property with serializable attribute?
If you are talking about in-process only, serialisation doesn't happen, the item is stored as a normal live reference to a .NET object, no serialisation happens.
If your session state is external (e.g. database) then obviously they need to be serialised at that point.
With regards to your specific point, there is no difference between what you are doing and creating the SelectList object manually and passing that into the session.
If I were you, I would strongly recommend that you do not store objects like this in the session, try to keep it to classes that you control (and can mark as Serializable), because if you do need to switch to out-of-process storage, you won't need to re-engineer your code.
Serialization and passing a model (and some extra data) from the controller to the view (as indicated by the System.Web.Mvc.SelectList) are two very different things.
Serialization has to do with turning an object into a string (or binary array) and Deserialization back from a string (or binary array) to an object.
The model passed back and forth on MVC is what the view should render. You're probably looking for a single property in that model (say countryID) to be displayed in a drop down list (or an html <select> or more generally a combo box). This bundle of wrapping data (say - the list of countries - Id and name pairs) should be passed on via a ViewBag or ViewData.
A SelectList should NOT be done on session as storing it is a big waste of memory. It will just linger there in memory long after the user has received his HttpResponse. A select list is just a list of options in the combo box, and as such it is not serializable (although it's content might be). You should really make the distinction between "the data inhabiting the combo box" (thin object) and "the combo box itself" (fat object). In this example - between the countries (which are an IEnumerable), and the UI element. Serializing a UI element doesn't make sense, and should always be avoided.

How to serialize complex objects and put them in a ViewState?

I have an object of type List<SPSection>, the SPSection is a custom class that contains a string and a List<SPListItem>, SPListItem is a SharePoint object representing an item.
I want to store this in a ViewState, but I don't know how to do this. Is there a way to serialize this or convert it to some binary string, so that I could put it in a ViewState. Also when getting the value back from the ViewState, how can I convert it back to List<SPSection>.
Thanks
Don't do this. SPListItem instances cannot be retained between requests. They depend on the respective SPList instance, which in turn depends on SPWeb + SPSite, both instantiated automatically and provided through SPContext.
What you can do is retain item IDs between requests. Your custom classes need to be binary serializable, i.e. marked with the [Serializable] interface. You then just store your object under a given key into the view state: ViewState["MyObjects"] = myObjects;.

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.

How to determine which classes are serializable

I am changing my ASP.NET app to use a web farm. To do this, I need to change the session state from in-proc to a State Server. To do this, it is my understanding that the classes that are used must be marked as serializable. How can you tell if that is possible with a class? Will you get an error at compile time if it is not possible?
In answer to your first question about how to tell whether or not a class is serializable, see the following discussion. How to check if an object is serializable in C#
Unfortunately, .net has surprised me with bizarre behavior when I try to serialize objects that I think should be serializable.
For example, in my WCF projects, I can serialize and transmit DataSet objects. However, if I try to serialize and transmit DataTable objects, I end up with a blank DataTable. It took me a while to track that one down.
Therefore, I would suggest that you do at least some rudimentary testing of what happens when you try to serialize custom classes.
You won't get a compile-time exception, since compile-time doesn't really know whether the objects will need to be serialized. You'll get a SerializationException when IIS attempts to serialize your objects.
You can write a short snippet that attempts to serialize and de-serialize the objects in question... use a BinaryFormatter to do the serialization, and a FileStream to write to.
The ObjectBrowser will tell you if an existing class implements ISerializable. If you're looking at your own objects to serialize, keep in mind that classes must really be designed for serialization if they are intended to be serialized, otherwise there are gotchas. For example, from the MSDN help:
The order in which objects are deserialized cannot be guaranteed. For example, if one type references a type that has not been deserialized yet, an exception will occur.
I recommend reading up in ISerializable... here's a link: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializable.aspx
EDIT: Here is a simple example of serialization and deserialization... just replace the Exception I'm serializing with your own objects:
BinaryFormatter formatter = new BinaryFormatter();
Exception serializedException = new Exception("Testing serialization");
Exception deserializedException;
using (FileStream fileStream = new FileStream(#"C:\SerializationTest.txt", FileMode.CreateNew)) {
formatter.Serialize(fileStream, serializedException);
}
using (FileStream readStream = new FileStream(#"C:\SerializationTest.txt", FileMode.Open)) {
deserializedException = formatter.Deserialize(readStream) as Exception;
}
if (deserializedException != null) {
throw deserializedException;
}

Resources