ASP.NET and Attributes

Alright, this is a bit tricky ...

I have a set of Attributes that I want to 'inject' into both User Controls and Pages (System.Web.UI.Page and System.Web.UI.UserControl).

In order to use the Attributes, I need about three methods and some inheritence. I define a class that inherits from Page and one that inherits from UserControl that define my Abstract Methods ( GetAttributes(); ) that loads in the OnLoad() event of the control, and a System.Attribute member field for an attribute of the proper type property in the inheriting class. The code is as follows. My question is ...can I do this a little more efficiently? I just want to clean up redundancy. is there a cleaner way to access the attributes of a class?

[ AttributeName ]
public abstract class WebPage : System.Web.UI.Page
{
  internal System.Attribute _attributes;

  public override void OnLoad()
  {
    GetAttributes();
   }
  public abstract void GetAttributes();
}

[ AttributeName ]
public abstract class WebUserControl : System.Web.UI.UserControl
{
  internal System.Attribute _attributes;

  public override void OnLoad()
  {
    GetAttributes();
   }
  public abstract void GetAttributes();
}

public class Page1 : WebPage
{
 public override void GetAttributes()
 {
   AttributesProperty = ...
 }
 
 public AttributeName AttributesProperty
 {
   get { return (AttributeName)_attributes;
   set { _attributes = value;
 }
}
LVL 2
derekthorntonAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

kbaltrinicCommented:
I am not clear as to what you mean by 'injecting an attribute' by your code I think you mean that you want to test within a class whether or not the class has a particular attribute or return the attributes that it has.  If that is the case the following code should work:

            public object[] Attributes()
            {
                  return this.GetType().GetCustomAttributes(true);
            }
derekthorntonAuthor Commented:
Not quite ...I'm trying to have it automatically retrieve attributes at runtime, I just want it to run cleaner than having to have two copies of a class...
kbaltrinicCommented:
Sorry you may need to more fully explain your problem.  One of the things that is confusing me is the use of plural variable names decalared as single objects such as "System.Attribute _attributes;" I am not certain if you are tyring to detect the presense of a particular attribute by name or get a list of all custom attributes.  Assuming the latter, to my way of thinking the method I posted "retrieves attributes at runtime" and if you mean by "automatically" that you want your _attributes variable to just always be already populated when accessed by other code, I would do it this way:  

public abstract class WebPage : System.Web.UI.Page
{
      private System.Attribute[] __attributes;

      internal System.Attribute[] _attributes
      {
            get
            {
                  if(__attributes == null)
                  {
                        object[] attributes = this.GetType().GetCustomAttributes(true);
                        __attributes = new System.Attribute(attributes.Length);

                        for(int i = 0; i < attributes.Length; i++)
                              __attributes[i] = (System.Attribute)attributes[i];
                  }

                  return __attributes;
            }
      }
}

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
HTML5 and CSS3 Fundamentals

Build a website from the ground up by first learning the fundamentals of HTML5 and CSS3, the two popular programming languages used to present content online. HTML deals with fonts, colors, graphics, and hyperlinks, while CSS describes how HTML elements are to be displayed.

derekthorntonAuthor Commented:
Alright, suppose I have three custom attributes.

Att1, Att2, and Att3.

I have the following -- I want to get Att1 into Attributes1, and so forth. But let's ASSUME for a moment that I don't know the index of Att1,2, and 3. i.e. I'd like to be able to just call a "get" on each one and it pull out whichever Attribute Index matches.

[ Att1 ][ Att2 ][ Att3 ]
public abstract class WebPage : System.Web.UI.Page
{
  // ...

  public Att1 Attributes1
  {
    // ...
  }

 public Att2 Attributes2
 {
  // ...
 }
 public Att3 Attributes3
 {
  // ...
 }
}
kbaltrinicCommented:
if your attributes are of different types would this not be what you are looking for?  Somehow I suspect npt but I am at least starting to grasp the outline of the problem. :-)

 public Att1 Attributes1
  {
    object[] attributes = this.GetType().GetCustomAttributes( typeof(Att1), true);
    //Assumine there is never more than one attribute of type Att1 declared on the class
    return attributes.Length == 0 ? (Att1)null : (Att1)attributes[0];
  }

derekthorntonAuthor Commented:
  return attributes.Length == 0 ? (Att1)null : (Att1)attributes[0];

that line is the problem. Let's assume for a moment that I cannot know what the index will be. What can I do?
kbaltrinicCommented:
Because if type Att1 does not have any subtypes, then you can't ever have more than one element in your attributes array.  So it is either attributs.Length = =0 or attributes lenght == 1.  The only time attributes.Length > 1 can be the case is if the types Att1, Att2 and Att3 all derive from type AttBase and change your GetCustomAttributes to be the following:
object[] attributes = this.GetType().GetCustomAttributes( typeof(AttBase), true);

Then if you declared [Att1][Att2] on the class, attributes.Lenght == 2 would be true.  Even in this case you could is the following

property Att1 Attribute1
{
  get
  {
    object[] attributes = this.GetType().GetCustomAttributes( typeof(AttBase), true);
    foreach(object a in attributes)
      if (a is Att1) return a;
    return null;
   }
}
kbaltrinicCommented:
Sorry for the typoes, I was typing fast and should have proof read my response, but I think you can follow the point.  Let me know if you have any questions.
derekthorntonAuthor Commented:
So then iterating the collection using a base class will still work?

i.e.

AttributeA : System.Attribute
AttributeB : System.Attribute

when iterated using a foreach as you've shown

[ AttributeA ][ AttributeB ]
class AttributesTesting
{
 //...
   object[] __attributes = GetType().GetCustomAttributes( typeof( System.Attribute ), true );

   foreach ( object _attribute in __attributes )
   if ( _attribute is AttributeA )
      return _attribute;
   return null;
}

would return __attributes[0] ,and if I said "is AttributeB", it would return __attributes[1]? is this correct? so typecasting them down doesn't degrade the inheritence tree? Since they are being iterated as " System.Attribute ", I wasn't sure if they would still register as "AttributeA" and "AttributeB".
kbaltrinicCommented:
look at the docs for the is opperator.  X is TypeA returns true in any the cast (TypeA)X would succeed.  If TypeSubA is a subclass of TypeA  and X is of TypeSubA then X is TypeA would also evaluate to true.   If you need to test if X is of TypeA exaclty then you can do X.GetType == typeof(TypeA)  but I think I may be digressing.  In both these cases the fact that X as avariable is declares as object is not relevant.  .Net alway looks at the actual type of the object.  If you do something like object a = new Att1() and test : a is Att1 you get true, just as if you checked a.GetType == typeof(Att1) you also get true.
derekthorntonAuthor Commented:
Just to followup -- this is my finalized XmlSerialization class.

using System;
using System.Xml;

namespace Forum.Serialization
{
      public struct XmlSerializer
      {
            // ===================================================== //                                                  
            #region// ================== SERIALIZATION ==================== //
            // ===================================================== //

            /// <summary>
            /// Serialize any given type into Xml
            /// </summary>
            /// <param name="filename">Filename of serialized .xml file</param>
            /// <param name="instance">Instance of an Xml Serializable object</param>
            /// <param name="type">Type of Xml Serializable object</param>
            /// <param name="included">Additional Xml Serializable objects to include</param>
            public static void Serialize ( String filename, Object instance, Type type , params Type[] included  )
            {
                  // this will make serialization a little easier on the fly --
                  //            the object passed through 'instance' is iterated with
                  //            all of the attributes attached -- the attributes that
                  //            match the type given are passed on, and the rest will
                  //            simply be discarded from the serialization, unless it
                  //            is a specified type in 'included'.
                  if ( type != instance.GetType() )
                  {
                        System.Object[] __attributes =
                              instance.GetType().GetCustomAttributes(type,true);

                        foreach( object _attribute in __attributes )
                              if ( _attribute.GetType() == type )
                                    instance = _attribute;
                        __attributes = null; // clean up the __attributes array
                  }

                  // construct a serialization stream, include any additional
                  // types as needed
                  System.Xml.Serialization.XmlSerializer XmlFormatSerializer
                        = new System.Xml.Serialization.XmlSerializer( type, included );

                  // specify the layout encoding of the xml document
                  XmlTextWriter XmlFormatWriter =
                        new XmlTextWriter( filename, System.Text.Encoding.UTF8 );

                  // specify the layout schema of the xml document
                  XmlFormatWriter.Formatting = Formatting.Indented;

                  try
                  {
                        // attempt to serialize the object and all related types --
                        //            if serialization fails, then the process is aborted
                        XmlFormatSerializer.Serialize( XmlFormatWriter, instance );
                  }
                  catch
                  {

                  }
                  finally
                  {
                        // flush the xml writer and formatter out of memory
                        //            -- flush occurs regardless of serialization
                        XmlFormatWriter.Flush();  XmlFormatWriter.Close();
                  }
            }

            #endregion
            // ===================================================== //

            // ===================================================== //                                                  
            #region// ================= DESERIALIZATION =================== //
            // ====================================================== //

            /// <summary>
            /// Deserialize an .xml file into an object
            /// </summary>
            /// <param name="filename">Filename of serialized object</param>
            /// <param name="type">Type of object to deserialize</param>
            /// <param name="included">Additional Xml Serializable objects to include</param>
            /// <returns></returns>
            public static object Deserialize( String filename, Type type, params Type[] included)
            {
                  // construct a serialization stream, include any additional
                  // types as needed
                  System.Xml.Serialization.XmlSerializer XmlFormatSerializer
                        = new System.Xml.Serialization.XmlSerializer( type, included );

                  // construct an xml reader to parse the deserialization stream
                  XmlTextReader XmlFormatReader = new XmlTextReader( filename );

                  try
                  {
                        // attempt to deserialize the object and all related types --
                        //            if deserialization fails, then the process is aborted
                        return XmlFormatSerializer.Deserialize( XmlFormatReader );
                  }
                  catch
                  {
                        return null;
                  }
                  finally
                  {
                        // close the xml serialization reader, regardless of success
                        XmlFormatReader.Close();
                  }
            }

            #endregion
            // ===================================================== //
      }
}
kbaltrinicCommented:
This part still makes no sense to me:

               if ( type != instance.GetType() )
               {
                    System.Object[] __attributes =
                         instance.GetType().GetCustomAttributes(type,true);

                    foreach( object _attribute in __attributes )
                         if ( _attribute.GetType() == type )
                              instance = _attribute;
                    __attributes = null; // clean up the __attributes array
               }

As I read it, you check if the instance‚Äôs type is the same as Type-if it is then you just serialize instance, simple enough.  But if the type of instance is not Type, then you get a list of all the attributes of Instance that are of type Type? That presumes that Type refers to subtype of System.Attribute or __Attributes will have zero elements.  So is instance supposed to be an attribute or a class with attributes attached? There seems to be some confusion here in my mind.

This confusion continues.  Presuming that Type really was an subtype of System.Attribute and that Instance did have attributes of type Type attached to it, the code goes on to replace instance with the attribute of Type that was attached to instance.  Why is the class that HAS the attribute, being replaced BY the attribute itself?
derekthorntonAuthor Commented:
Because that's the goal of the serialization. The reason I am using attributes is because the class itself cannot be serialized. The classes that will be utilizing this inherit from System.Web.UI.Page and System.Web.UI.UserControl, which cannot be serialized. I want to include a way to save information from these pages into XML, so I use attributes that the user can call from HTML code ( Using <% %> ) and in C# code to replace inline parameters and properties. These Attributes are serialized, since the classes themselves cannot be. Instance is a class that has attributes attached to it.
derekthorntonAuthor Commented:
This might explain better. Here is a class that uses it.

using System;

namespace Forum.Html.Pages
{
      [ Forum.Web.WebAttribute( "Index" ) ]
      public class Index : System.Web.UI.Page
      {
            // ===================================================== //
            #region // =================== CLASS METHODS =================== //
            
            /// <summary>
            /// Raises the <see>WebPage.OnLoad</see> event.
            /// </summary>
            /// <param name="e">EventArgs to handle the event.</param>
            protected override void OnLoad(EventArgs e)
            {
                  base.OnLoad (e);


                  Serialization.XmlSerializer.Serialize
                        (
                              System.Web.HttpContext.Current.Request.PhysicalApplicationPath + @"/index.xml",
                              this, typeof(Forum.Web.WebAttribute)
                        );
            }

            #endregion
            // ===================================================== //

            // ===================================================== //                                                  
            #region// =============== ASP.NET FORM DESIGNER =============== //
            // ===================================================== //

            override protected void OnInit(EventArgs e)
            {
                  //
                  // CODEGEN: This call is required by the ASP.NET Web Form Designer.
                  //
                  InitializeComponent();      base.OnInit(e);
            }
            
            /// <summary>
            ///            Required method for Designer support - do not modify
            ///            the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
            }

            #endregion
            // ===================================================== //
      }
}
derekthorntonAuthor Commented:
I'm going to have a CascadingStyleSheet attribute, and other sorts of things to define HTML structures. I attach these to classes so that they can be serialized and stored dynamically in different folders (since this will be supporting a skin system). That way, I can write an interface to interact with the serialized classes to create a 'skin designer' that will create XML templates into different skin folders, the attributes let me easily use the interop of C# to call and specify things without unneccesary overhead of declaring properties and the like in every single class.
derekthorntonAuthor Commented:
And just to help clarify, here is WebAttribute.

using System;

namespace Forum.Web
{
      [ AttributeUsage ( AttributeTargets.All ) ]
      [ System.Xml.Serialization.XmlRoot( "WebAttribute" ) ]
      public class WebAttribute : System.Attribute
      {
            // ===================================================== //
            #region // =================== MEMBER FIELDS =================== //
            
            /// <summary> Property backer for the ID property </summary>
            protected internal string __id = System.String.Empty;

            #endregion
            // ===================================================== //

            // ===================================================== //
            #region // ==================== CONSTRUCTORS =================== //
            
            /// <summary>
            /// Constructs a new WebAttribute
            /// </summary>
            public WebAttribute( ): this( null )
            {
                  //
                  // Default Constructor
                  //
            }

            /// <summary>
            /// Constructs a new WebAttribute
            /// </summary>
            /// <param name="id">The Attribute ID</param>
            public WebAttribute( System.String id )
            {
                  __id = id; // Specify the WebAttribute ID
            }

            #endregion
            // ===================================================== //

            // ===================================================== //
            #region // ================== CLASS PROPERTIES ================= //
            
            /// <summary>
            /// Gets or Sets the ID
            /// </summary>
            [ System.Xml.Serialization.XmlElement( "ID" ) ]
            public System.String ID
            {
                  get { return __id; }
                  set { __id = value;}
            }

            #endregion
            // ===================================================== //
      }
}
derekthorntonAuthor Commented:
Here. I did some more tweaking. Here's a completed example using the code.

using System;

namespace Forum.Html.Pages
{
      [ Forum.Web.HtmlWebPage( "Index" ) ]
      public class Index : System.Web.UI.Page
      {
            // ===================================================== //
            #region // =================== MEMBER FIELDS =================== //
            
            /// <summary> HtmlWebPage Attribute Settings for Serialization </summary>
            protected internal Forum.Web.HtmlWebPage __attributes = null;

            #endregion
            // ===================================================== //

            // ===================================================== //
            #region // =================== CLASS METHODS =================== //
            
            /// <summary>
            /// Raises the <see>WebPage.OnLoad</see> event.
            /// </summary>
            /// <param name="e">EventArgs to handle the event.</param>
            protected override void OnLoad(EventArgs e)
            {
                  base.OnLoad (e);

                  HTML.Style.BackgroundColor = "FFFFFF";

                  Serialization.XmlSerializer.Serialize
                        (
                              System.Web.HttpContext.Current.Request.PhysicalApplicationPath + @"/skin/asgard/config/index.xml",
                              HTML, typeof(Forum.Web.HtmlWebPage)
                        );

                  HTML.Style.BackgroundColor = "";

                  HTML = ( Forum.Web.HtmlWebPage )Serialization.XmlSerializer.Deserialize
                        (
                              System.Web.HttpContext.Current.Request.PhysicalApplicationPath + @"/skin/asgard/config/index.xml",
                              typeof( Forum.Web.HtmlWebPage )
                        );

                  Response.Write(HTML.Style.BackgroundColor);
            }

            #endregion
            // ===================================================== //

            // ===================================================== //                                                  
            #region// =============== ASP.NET FORM DESIGNER =============== //
            // ===================================================== //

            override protected void OnInit(EventArgs e)
            {
                  //
                  // CODEGEN: This call is required by the ASP.NET Web Form Designer.
                  //
                  InitializeComponent();      base.OnInit(e);
            }
            
            /// <summary>
            ///            Required method for Designer support - do not modify
            ///            the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
            }

            #endregion
            // ===================================================== //

            // ===================================================== //
            #region // ================== CLASS PROPERTIES ================= //
            
            /// <summary>
            /// Gets or Sets the HTML elements of the WebPage ( Serializable )
            /// </summary>
            [ System.Xml.Serialization.XmlElement( "HTML" ) ]
            public Forum.Web.HtmlWebPage HTML
            {
                  get
                  {
                        if( __attributes == null)
                              __attributes = ( Forum.Web.HtmlWebPage )GetType().
                                    GetCustomAttributes( typeof( Forum.Web.HtmlWebPage ), true)[0];
                        return __attributes;
                  }
                  set
                  {
                        if ( __attributes == null )
                              __attributes = ( Forum.Web.HtmlWebPage )GetType().
                                    GetCustomAttributes( typeof( Forum.Web.HtmlWebPage ), true)[0];
                        __attributes = value;
                  }
            }

            #endregion
            // ===================================================== //
      }
}

using System;
using System.Drawing;

namespace Forum.Web
{
      // ===================================================== //
      #region // ==================== WebAttribute =================== //
      
      [ AttributeUsage ( AttributeTargets.All ) ]
      [ System.Xml.Serialization.XmlRoot( "WebAttribute" ) ]
      public abstract class WebAttribute : System.Attribute
      {
            // ===================================================== //
            #region // =================== MEMBER FIELDS =================== //
            
            /// <summary> Property backer for the ID property </summary>
            private string __id = System.String.Empty;

            #endregion
            // ===================================================== //

            // ===================================================== //
            #region // ==================== CONSTRUCTORS =================== //
            
            /// <summary>
            /// Constructs a new WebAttribute
            /// </summary>
            public WebAttribute( ): this( null )
            {
                  //
                  // Default Constructor
                  //
            }

            /// <summary>
            /// Constructs a new WebAttribute
            /// </summary>
            /// <param name="id">The Attribute ID</param>
            public WebAttribute( System.String id )
            {
                  __id = id; // Specify the WebAttribute ID
            }

            #endregion
            // ===================================================== //

            // ===================================================== //
            #region // ================== CLASS PROPERTIES ================= //
            
            /// <summary>
            /// Gets or Sets the ID
            /// </summary>
            [ System.Xml.Serialization.XmlElement( "ID" ) ]
            public System.String ID
            {
                  get { return __id; }
                  set { __id = value;}
            }

            #endregion
            // ===================================================== //
      }

      #endregion
      // ===================================================== //

      [ AttributeUsage ( AttributeTargets.All ) ]
      public class CascadingStyleSheetStyle : System.Attribute
      {
            // ===================================================== //
            #region // =================== MEMBER FIELDS =================== //
            
            /// <summary> Property backer for the background color </summary>
            private string __clrBackgroundColor = string.Empty;

            #endregion
            // ===================================================== //

            // ===================================================== //
            #region // ==================== CONSTRUCTORS =================== //
            
            /// <summary>
            /// Constructs a new CascadingStyleSheetStyle
            /// </summary>
            public CascadingStyleSheetStyle( ): base (  )
            {
                  //
                  // Default Constructor
                  //
            }

            #endregion
            // ===================================================== //

            // ===================================================== //
            #region // ================== CLASS PROPERTIES ================= //
            

            [ System.Xml.Serialization.XmlElement( "Background-Color", typeof(string) ) ]
            public string BackgroundColor
            {
                  get { return __clrBackgroundColor; }
                  set { __clrBackgroundColor = value;}
            }

            #endregion
            // ===================================================== //
      }

      [ CascadingStyleSheetStyle ]
      [ AttributeUsage ( AttributeTargets.All ) ]
      public class HtmlWebPage : WebAttribute
      {
            // ===================================================== //
            #region // =================== MEMBER FIELDS =================== //
            
            /// <summary> Property backer for the Cascading Style Sheet Style Attribute </summary>
            private CascadingStyleSheetStyle __style = new CascadingStyleSheetStyle();

            #endregion
            // ===================================================== //

            // ===================================================== //
            #region // ==================== CONSTRUCTORS =================== //
            
            /// <summary>
            /// Constructs a new HtmlWebPage
            /// </summary>
            public HtmlWebPage( ): base ( null )
            {
                  //
                  // Default Constructor
                  //
            }

            /// <summary>
            /// Constructs a new HtmlWebPage
            /// </summary>
            /// <param name="id">The HtmlWebPage ID</param>
            public HtmlWebPage( System.String id ) : base( id )
            {
            }

            #endregion
            // ===================================================== //

            // ===================================================== //
            #region // ================== CLASS PROPERTIES ================= //
            
            /// <summary>
            /// Gets or Sets the Cascading Style Sheet Style
            /// </summary>
            [ System.Xml.Serialization.XmlElement( "Style" ) ]
            public CascadingStyleSheetStyle Style
            {
                  get
                  {
                        if( __style == null)
                              __style = ( CascadingStyleSheetStyle )GetType().
                                    GetCustomAttributes( typeof( CascadingStyleSheetStyle ), true)[0];
                        return __style;
                  }
                  set
                  {
                        if ( __style == null )
                              __style = ( CascadingStyleSheetStyle )GetType().
                                    GetCustomAttributes( typeof( CascadingStyleSheetStyle ), true)[0];
                        __style = value;
                  }
            }

            #endregion
            // ===================================================== //
      }
}
using System;
using System.Xml;

namespace Forum.Serialization
{
      public struct XmlSerializer
      {
            // ===================================================== //                                                  
            #region// ================== SERIALIZATION ==================== //
            // ===================================================== //

            /// <summary>
            /// Serialize any given type into Xml
            /// </summary>
            /// <param name="filename">Filename of serialized .xml file</param>
            /// <param name="instance">Instance of an Xml Serializable object</param>
            /// <param name="type">Type of Xml Serializable object</param>
            /// <param name="included">Additional Xml Serializable objects to include</param>
            public static void Serialize ( String filename, Object instance, Type type , params Type[] included  )
            {
                  // this will make serialization a little easier on the fly --
                  //            the object passed through 'instance' is iterated with
                  //            all of the attributes attached -- the attributes that
                  //            match the type given are passed on, and the rest will
                  //            simply be discarded from the serialization, unless it
                  //            is a specified type in 'included'.

                  System.Object __instance = instance; // Xml Serializable Instance of an Object

                  if ( type != instance.GetType() )
                  {
                        System.Object[] __attributes =
                              instance.GetType().GetCustomAttributes(true);

                        foreach( object _attribute in __attributes )
                              if ( _attribute.GetType() == type )
                                    __instance = _attribute;
                        __attributes = null; // clean up the __attributes array
                  }

                  // construct a serialization stream, include any additional
                  // types as needed
                  System.Xml.Serialization.XmlSerializer XmlFormatSerializer
                        = new System.Xml.Serialization.XmlSerializer( type, included );

                  // specify the layout encoding of the xml document
                  XmlTextWriter XmlFormatWriter =
                        new XmlTextWriter( filename, System.Text.Encoding.UTF8 );

                  // specify the layout schema of the xml document
                  XmlFormatWriter.Formatting = Formatting.Indented;

                  try
                  {
                        // attempt to serialize the object and all related types --
                        //            if serialization fails, then the process is aborted
                        XmlFormatSerializer.Serialize( XmlFormatWriter, __instance );
                  }
                  catch
                  {

                  }
                  finally
                  {
                        // flush the xml writer and formatter out of memory
                        //            -- flush occurs regardless of serialization
                        XmlFormatWriter.Flush();  XmlFormatWriter.Close();
                  }
            }

            #endregion
            // ===================================================== //

            // ===================================================== //                                                  
            #region// ================= DESERIALIZATION =================== //
            // ====================================================== //

            /// <summary>
            /// Deserialize an .xml file into an object
            /// </summary>
            /// <param name="filename">Filename of serialized object</param>
            /// <param name="type">Type of object to deserialize</param>
            /// <param name="included">Additional Xml Serializable objects to include</param>
            /// <returns></returns>
            public static object Deserialize( String filename, Type type, params Type[] included)
            {
                  // construct a serialization stream, include any additional
                  // types as needed
                  System.Xml.Serialization.XmlSerializer XmlFormatSerializer
                        = new System.Xml.Serialization.XmlSerializer( type, included );

                  // construct an xml reader to parse the deserialization stream
                  XmlTextReader XmlFormatReader = new XmlTextReader( filename );

                  try
                  {
                        // attempt to deserialize the object and all related types --
                        //            if deserialization fails, then the process is aborted
                        return XmlFormatSerializer.Deserialize( XmlFormatReader );
                  }
                  catch
                  {
                        return null;
                  }
                  finally
                  {
                        // close the xml serialization reader, regardless of success
                        XmlFormatReader.Close();
                  }
            }

            #endregion
            // ===================================================== //
      }
}
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.