Wednesday, November 24, 2010

Should I build a "Windows" or "Web" App?

Hundreds of blogs have been written about the topic but I thought it would be worth re-visiting again.

A lot has changed in the last few years in the web world and has given some parity to the Windows vs Web app debate.  I don't think there is a clear winner but probably scenarios where one might make sense over the other.

Deployment/Bug  Fix process is one area I really think requires some consideration when choosing Windows vs.Web.  If Debbie in Accounting has a problem with a screen that only she uses... in the Windows world I can give her a new executable (via Click Once or XCopy, etc) and she's good to go; nobody else impacted.

In the web world, a production fix could require all the users to get out of the system.  If you're running a state-aware site... dropping in a new DLL will cause the sessions to restart.  (Note this applies to changing the code behinds; you can change the ASPX pages.)  To prevent this, you need a web application that is stateless (or uses cookies or some other method of storing information) so updates will not hose up everyone else.

Also web development tends to take longer than windows development because of the additional requirements such as security and optimizing performance.

Aside from that area, to me anyhow, there is a lot of similarities between the platforms.

Wednesday, November 10, 2010

Object Serialization in .NET

Serialization and its counter-process (Deserialization) is a mechanism to "package" an object for transport to another application or process.

You might want to send a stream of data over a web service, store it in a database, or need some type of interop way to transport an object across system.

The two main methods of serialization in .NET is the Binary and XML.  In a binary serialization, the object is converted to (get this) a binary stream; which is the fastest method of serialization.  Alternately with the XML serialization the stream is plain text which is better for interop.  One key note is that XML doesn't preserve the data type as well as binary but binary is really only useful for .NET to .NET type communication/transport.

Prerequisites to serialization... Serialization is not "free" in the sense that you have to do some work to make your classes/objects serializable.  The easiest way to do this is to mark your class with the attribute as shown here:

    [Serializable]
    public sealed class SomeObject
    {
        public int n1 = 0;
    }

This works because basic data types like int, string, etc .NET already knows how to serialize. However, if I had another custom class it would need to be marked as Seralizable as well.  This can has a cascading effect (all objects in the tree must be serializable [or marked as NonSerialized]) so keep that in mind when looking into this solution.

As I just alluded to if you want something to skip the serialization step then it needs to be marked as [NonSerialized] but keep in mind that object will be null when you Deserialize your object.

A simple example of how to serialize an object:

//Required namespaces
using System.IO; //required for stream
using System.Runtime.Serialization.Formatters.Binary; //required for binary formatter
using System.Runtime.Serialization; //required for Formatter Interface

SomeObject obj = new SomeObject();

IFormatter formatter = new BinaryFormatter();

Stream stream = new FileStream("MyFile.bin",
                                     FileMode.Create,
                                     FileAccess.Write, FileShare.None);

formatter.Serialize(stream, obj);
stream.Close();

As you see above we use a formatter. In this case we used the Binary Formatter but could have used the XML Formatter as well.  The formatter as the name suggests converts the object into the specified serial format and puts it into a stream.

In this case I put the object into a file but I could modify the code and store it in a string or some other container.

As I mentioned earlier now with this object stored in a stream/file/whatever we can now do with it what we please.  For our example, we'll say that this binary goes into a folder for processing by a Windows Service.  In the service it is very simple to pull the object back into memory and start working with it...

FileStream fs = new FileStream("MyFile.bin", FileMode.Open);
BinaryFormatter readFormatter = new BinaryFormatter();
SomeObject serialObj = (SomeObject)formatter.Deserialize(fs);

Just like that we now have our object back and can start working with it.

Limitations...  Some things to keep in mind when doing serialization ... I already mentioned that data that is marked as NonSerialized will be blank/null in the object.  But also keep in mind deserializing an object is not the same as creating a new object.  Therefore, the constructor don't be called.

Also, only public information is serialized.

Custom Serialization... I didn't touch on it but you can inherit the ISerializable interface and invoke your own GetObjectData method to write your own custom serialization for an object.  By default, you don't need to do this unless you have special requirements for the output of the serialization (say your formatting your XML to a schema that another system will consume, etc).

Thursday, November 4, 2010

Alternatives to Try Catch type casting

Back in the early stages of .NET in C# there were limited tools to determine if a cast would work or not.

So typically you'd see something like

int myInt = 0;

try
{
   myInt = (int)TextBox1.Text //some input
}
catch
{
   MessageBox.Show("This is not a valid integer.");
  return;
}

In 2.0 the TryParse came along.  TryParse will return a bool (if the cast worked or not) and put the value of the successful cast into a value.

Example:

int myInt = 0;

if !(int.TryParse(TextBox1.Text, out myInt))
{
  MessageBox.Show("This is not a valid integer.");
}

Visually, this is a little less code but is also a more legitimate way of testing your casting.  Really, you could do a lot more checks using Regular Expressions, etc but something like this is a simple way to do validation in simple scenarios... IE... you just need there to be a number in there not a number with a decimal and x number of digits before and after, etc.

That example was for simple data types... but we can use IS for more complex data types like objects.

The IS keyword basically evaluates if the object to the left of the IS inherits (or is actually) of the same type.  This is useful in places where you want to pass an object as something simpler than it really is to made your function more versatile.

Using the Try Catch paradigm we could do something like this...

public static boolean SaveData(object myObj)
{
     SomeBaseClass b = null;

      try
     {
          b = (SomeBaseClass)myObj;
          return b.SaveData(); //assumes that method returns bool
      }
     catch
     {
         return false;
      }
}

A simpler way is to use the IS keyword...


public static boolean SaveData(object myObj)
{
    SomeBaseClass b;

    if (myObj is SomeBaseClass)
  {
          b = (SomeBaseClasse)myObj;
         return b.SaveData();
   }
  else
  {
   return false;
  }
}

Now in a case like this I'd probably make my SaveData function accept a SomeBaseClass object instead of a regular object and call the save... or make the object implement some type of interface that any object wanting to use this method could call.

However, this is just to give an example of how you can evaluate objects.  Maybe you support some types of objects (or handle them slightly differently) and want to run them all through the same method and this way you can easily do that.