Tuesday, February 27, 2007

NET : Ignore field for XML Serialization

You can ignore certain public field from being serialize if the value for that field
is not specified.

XmlSerializer recognize a specific pattern during serialization to ignore
or include a field into the serialization.

Here are the steps :
1) You create a public field (EG : public int Age).
2) Create a boolean field using the convention PropertyNameSpecified (EG : public boolean AgeSpecified).
3) Apply XmlIgnoreAttribute attribute to the boolean property.

Refer to the following code.

public class Customer
{
public string Name;
public int Age;

[XmlIgnore()]
public bool AgeSpecified;
}


Here is the code to serialize the Customer object. Notice I set the AgeSpecified to false to tell the XmlSerializer not to serialize the Age field.

static void SerializeData()
{
Customer c = new Customer();
c.Name = "Bob";
c.Age = 21;
c.AgeSpecified = false;

XmlSerializer serializer = new XmlSerializer(typeof(Customer));
FileStream fs = new FileStream("simple.xml", FileMode.Create);

// Serialize the object
serializer.Serialize(fs, c);
fs.Close();
}


If you open simple.xml in notepad, you will see that there is no Age field.





Run the following code to deserialize the object from the file.

static void DeserializeData()
{
Customer c = null;

XmlSerializer serializer = new XmlSerializer(typeof(Customer));
FileStream fs = new FileStream("simple.xml", FileMode.Open);

c = (Customer)serializer.Deserialize(fs);
fs.Close();

Console.WriteLine("Age : " + c.Age);
Console.WriteLine("Specified : " + c.AgeSpecified);
}





Now run the serialize and deserialize code again, but this time set the AgeSpecified to true, and below is
the output :





Labels:

Monday, February 05, 2007

Exception : {Throw} vs {Throw ex}

I have seen two way how people typically throw exception:

Example 1:
try
{
//...
}
catch(Exception ex)
{
throw;
}


Example 2:
try
{
//...
}
catch(Exception ex)
{
throw ex;
}



While both accomplish the objective, which is to throw the exception back to the
caller for further action, it has substle difference.

In the first example, it is considered you are re-throwing the existing exception.
The exception contain the full stack frame from where the exception is orginated
all the way up to the caller stack frame.

Run the sample code below, and you shall see the stack trace as below. Notice, at each stack frame, the stack trace contain the stack frame of where the exception is orginated all the way up to the caller stack frame.



In the second example, it is considered you are throwing a new exception.
The exception only contain stack frame of the caller and the frame which throw
the exception. Run the sample code again, but this time change the throw to throw ex. This time, you will notice at each stack frame, the stack trace only contain the stack frame of the callee and the caller. So, you lose information of where the exception is originated. This can make locating the source of error very difficult.



Sample Code

class Class1
{
[STAThread]
static void Main(string[] args)
{
try
{
Console.WriteLine(f1());
}
catch(Exception ex)
{
Console.WriteLine("---Exception in Main()---");
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace.ToString());
}
Console.ReadLine();
}

static int f1()
{
try
{
return f2();
}
catch(Exception ex)
{
Console.WriteLine("---Exception in f1()---");
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace.ToString());
throw;
}
}

static int f2()
{
try
{
return f3();
}
catch(Exception ex)
{
Console.WriteLine("---Exception in f2()---");
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace.ToString());
throw;
}
}

static int f3()
{
int a = 0;
int b = 1;

try
{
return b /a;
}
catch(Exception ex)
{
Console.WriteLine("---Exception in f3()---");
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace.ToString());
throw;
}
}
}

Labels: