Thoughts from Dan Miser RSS 2.0
 Monday, January 08, 2007
While the XmlIgnore/Specified pattern to control serialization is very useful, it could be overkill for simpler serialization scenarios.

When you create an object with a bool field, that field is initialized and defaulted to the value of false. Under normal conditions, this value will get serialized every time. However, what if we only care about capturing that value when the value is true? It turns out that we can use DefaultValueAttribute. The first thing that may stand out to you is that this attribute lives in the System.ComponentModel namespace, and not in an XML namespace. The online help also mentions that this is used for visual designers and code generators. XmlSerializer also uses this attribute to decide whether or not to stream the value during serialization, since it's really a form of a code generator (more on that in a later post). If the value of the field or property matches the value that you specify in the DefaultValueAttribute, then that property will not be streamed.

Using an XmlAttributeAttribute, you can specify that a certain property will be expressed as an XML attribute instead of an XML element. To demonstrate both of these concepts, see the following code:

public class Url

{

    [XmlAttribute("address")]

    public string Address;

    [XmlAttribute("primary"), DefaultValue(false)]

    public bool Primary;

    public Url()

    {

   }

}

static void Main(string[] args)

{

    Url u = new Url();

    u.Address = "http://testing/";

    string xml = GetXMLFromObject(u);

    Console.WriteLine(xml);

}

This produces roughly the following output (XML namespace information is stripped here. I will show how to do this in code with a future post). Notice that the Primary attribute is not generated because it matches the DefaultValue.

<?xml version="1.0" encoding="utf-16"?>

<Url address="http://testing/" />

Monday, January 08, 2007 9:09:43 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -
.NET | XML
 Friday, January 05, 2007
David Hervieux posted a link to some Serialization FAQs in a comment to my last post. This material is good, and actually forced me to go back through what I wanted to cover, since I didn't want to just add posts that duplicate what can be found easily on the web. I'll still move forward with a few items in XML serialization that I think are unique.

The XMLIgnore attribute is used to tell the XmlSerializer that this field is transient, and should not be (de)serialized. The most typical use for this would be to mark calculated fields with this attribute. This is an easy customization that helps your serialization process, but it leaves a bit to be desired. It's an "all or nothing" approach, where the property is either streamed or not.

This MSDN article hints at what to do to get more fine-grained control of this aspect of serialization. Basically, you create a public boolean field or property named propertyNameSpecified for the property you want to control. The XmlSerializer uses this convention to determine whether or not to include the associated property for serialization. Since this new Specified field will be eligible for serialization, be sure to mark it with the XmlIgnore attribute to prevent it from being serialized.

A very simple code listing showing how this all fits together:

    public class Player

    {

        private int number;

        private string name;

        [XmlElement("jerseyNumber")]

        public int Number

        {

            get { return number; }

            // You could add more logic here to only set NumberSpecified based on some criteria

            set { number = value; NumberSpecified = true; }

        }

        [XmlElement("playerName")]

        public string Name

        {

            get { return name; }

            set { name = value; }

        }

        [XmlIgnore]

        public bool NumberSpecified;

    }

The downsides to using this techniques are:
  • It requires another field, and some custom logic to make this work.
  • It requires that the Specified field be marked as public, exposing it to consumers of the library. There is no real reason why the XmlSerializer couldn't use reflection to get at a non-public member.
  • If you use a property, it must be a full read-write property. A read-only property could very well suffice here, and make your code easier to maintain.

      Download the very simple sample showing this behavior here.

    • Friday, January 05, 2007 1:37:20 PM (Central Standard Time, UTC-06:00)  #    Comments [2] -
      .NET | XML
       Wednesday, December 27, 2006
      Serializing between .NET objects and XML files, and vice versa, is extremely easy, yet flexible and powerful. I'll be blogging a few entries about this topic in the days to come. This entry will set the stage, showing the basics of XML serialization.

      Assume you have a (stripped down) class definition like this:

          public class Player

          {

              [XmlElement("jerseyNumber")]

              public int Number { get; set; }

              [XmlElement("playerName")]

              public string Name { get; set; }

          }

      And you wanted to read/write an XML file that looked like this:

      <Player>

        <jerseyNumber>23</jerseyNumber>

        <playerName>Dan</playerName>

      </Player>

      The key to making this happen is the XmlSerializer class. This is the class that will convert between public properties and XML elements. You can also decorate your class with simple attributes to coerce your class into generating custom XML (i.e. XML attributes, hide or rename elements, etc.).

      Here are a couple of helper methods, and a sample that uses them to show you how all of this comes together.

              static string GetXMLFromObject(object obj)

              {

                  XmlSerializer ser = new XmlSerializer(obj.GetType());

       

                  StringBuilder sb = new StringBuilder();

                  using (XmlTextWriter writer = new XmlTextWriter(new StringWriter(sb)))

                  {

                      writer.Formatting = Formatting.Indented;

                      ser.Serialize(writer, obj);

                      return sb.ToString();

                  }

              }

       

              static object CreateObjectFromXML(string xml, Type xmlType)

              {

                  XmlSerializer ser = new XmlSerializer(xmlType);

                  object obj = null;

                  using (StringReader reader = new StringReader(xml))

                  {

                      obj = ser.Deserialize(reader);

                  }

                  return obj;

              }

       

              static void Main(string[] args)

              {

                  Player p = new Player();

                  p.Number = 23;

                  p.Name = "Dan";

                  string xml = GetXMLFromObject(p);

                  Console.WriteLine(xml);

                  Console.WriteLine();

       

                  Player q = (Player)CreateObjectFromXML(xml, typeof(Player));

                  Console.WriteLine(q.Number + " --> " + q.Name);

                  Console.ReadLine();

              }

      Other references:
      XML Serialization in the .NET Framework

      Wednesday, December 27, 2006 11:05:11 AM (Central Standard Time, UTC-06:00)  #    Comments [1] -
      .NET | XML
       Monday, December 18, 2006
      It looks like lots of changes are going on here. First off, I am now working in C# full-time since I took a job with SpiderLogic. I think this is going to be a great opportunity for me to expand and grow again. I doubt I will ever be out of Delphi completely, but my new focus is definitely going to be on .NET. As such, I contacted DelphiFeeds to tell them to use just my Delphi category. Someone contacted me after a VS.NET post and mentioned that it seemed strange to see that on the Delphi feed, and I agreed. I don't want to clutter a very good Delphi resource up with blog posts about a competing IDE and/or language. However, if you like what you read here, I would encourage you to subscribe to my main feed, too.

      The other change is on my blog. With prompting from Steve Trefethen, I made the switch to dasBlog. I had set dasBlog up for our internal blog at my last place of employment, and it worked great. I got tired of the lack of options that .Text provided, so I felt I had to do something. dasBlog provides a couple of features that I really wanted, like searching and better spam prevention. In addition, it's actively being developed.

      Converting was fairly painless. I read a post by Scott Hanselman about migrating to dasBlog, and from there I found some code to help automate the conversion. There are several dead links out there, so finding this one was a definite time saver. I changed the code slightly to get categories out of .Text and into dasBlog. I changed the main SQL statement to the one below, and then just added a line of code to add that category information to the dasBlog conversion code. This works for me because I didn't use multiple categories for a post.

      
      SELECT 
        blog_Content.ID, blog_Content.Title, blog_Content.DateAdded, blog_Content.SourceUrl, blog_Content.PostType, 
        blog_Content.Author, blog_Content.Email, blog_Content.SourceName, blog_Content.BlogID, blog_Content.Description, 
        blog_Content.DateUpdated, blog_Content.TitleUrl, blog_Content.Text, blog_Content.ParentID, blog_Content.FeedBackCount, 
        blog_Content.PostConfig, blog_Content.EntryName, blog_LinkCategories.Title AS CategoryTitle
      FROM blog_Content 
        LEFT OUTER JOIN blog_Links ON blog_Links.PostID = blog_Content.ID 
        LEFT OUTER JOIN blog_LinkCategories ON blog_Links.CategoryID = blog_LinkCategories.CategoryID
      

      I was worried about old URLs that were used from my .Text blog, but the later versions of dasBlog already do URL rewriting to make that transition absolutely seamless. I also use w.bloggar for writing my entires, so I had to change some settings to get that to work with dasBlog. Lastly, I updated my RSS feed to use FeedBurner.

      All in all, I'm quite happy with how things turned out. If you see any problems, please feel free to let me know.

      Monday, December 18, 2006 9:42:22 AM (Central Standard Time, UTC-06:00)  #    Comments [2] -
      Delphi
       Wednesday, December 13, 2006
      I just finished reading this book by Jimmy Nilsson, and I have a mixed review of it. The general consensus (e.g. see here and here) out there is that this book is one of the most fantastic books out there on how to architect systems using C#. I do agree that the book is well-written, with a very unique insight into the thoughts and decisions to make along the way in designing a robust application from an OO viewpoint. It got me thinking about how I view TDD and architecture from a domain model perspective.

      The negative for this book outweighs the benefits, in my opinion. The fact that there is no sample/reference application leaves the reader frustrated. If the design techniques can't even be proven in a simple application that was discussed over 450 pages, how can one have faith to apply the techniques in their own production applications? I searched on the book's forum, but the general attitude there is "If you need a sample, you can't understand all the decisions made to create your own application". My reply to that is "Hogwash". As mentioned earlier, 450 pages were used to talk about why certain architectural decisions were made.

      All in all, I would skip this book until the major deficiency of no sample application is fixed.

      Wednesday, December 13, 2006 10:42:00 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -
      .NET
       Tuesday, December 12, 2006
      When John Kaster of CodeGear (formerly Borland) came to Milwaukee last year, he showed a demo of some software running on a Pocket PC (PPC). The cool part was he was working on the actual PPC device itself but broadcasting the PPC screen to the overhead projector through his laptop.

      I checked with him this week as I'm doing more work in this area now, and he told me that the free tool to get this done is called ActiveSync Remote Display. It is part of the Windows Mobile Developer Power Toys, available from Microsoft. I also tested it this week, and I can report that it still works with Active Sync 4.2.

      Tuesday, December 12, 2006 8:36:00 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -
      .NET | Compact Framework
       Friday, December 08, 2006
      Rory Blyth has a couple of good videos on MSDN TV, showing how to use MSSQL Mobile Edition on a CF device. They are older, so they don't cover all the new nomenclature (and probably newer features), but there are a couple of good tips and tricks in there, and it contains good coverage of Remote Data Access, a technology that will help synchronize data to/from MSSQL Compact Edition.

      Links:

      Friday, December 08, 2006 9:56:00 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -
      .NET | Compact Framework
       Thursday, December 07, 2006
      Here's my experience getting this combination of tools to work properly. At times, it was extremely frustrating, and other times it was confusing. MS has not helped much what with obsolete, out-dated, mis-named, and near impossible to find products. Hopefully the RTM version will have everything stitched together nicely so all you have to do is double click a setup file. It would be even better to have log information easily and readily available for the installs. If you want to develop with these technologies, give these steps a try. I don't claim that they are authoritatve or complete, but I documented as much as I could capture.

      1. ActiveSync Setup 4.2 - required for several other installs later on.
      2. Windows Mobile 5.0 PPC SDK - adds new platform targets and emulators to support PPC development with WM 5.0. There is also a Windows Mobile 5.0 SDK for Smartphone download available if you prefer that instead.
      3. VS.NET 2005 SP1 Beta - I couldn't get to this page from the MS site anywhere, but I was able to find a link to take me to the download location. I can't swear that this is entirely required, as I installed the other tools without it on one PC, and it seemed to work OK.
      4. Microsoft SQL Server 2005 Everywhere Edition Tools for Visual Studio 2005 Service Pack 1 Beta - This install specifically states that VS.NET SP1 Beta is required. As you can see from the title, it also mentions SqlServer Everywhere, but ignore that inconsistency. The MSSQL team has renamed the product to SQL Server Compact Edition. This naming problem is supposed to be fixed by the time MS releases MSSQL Compact Edition.

        I also ran into a problem when uninstalling this application. I would get the following error when trying to reinstall it:

        
        The upgrade patch cannot be installed by the Windows Installer service
        because the program to be upgraded may be missing, or the upgrade path
        may update a different version of the program. Verify that the program
        to be upgraded exists on your computer and that you have the correct
        upgrade patch
        

        I finally did a Repair install on VS.NET, and I was able to install the tools again.

        However, even with all of that, I would recommend installing this because it allows for things like Server Explorer to be used on SDF files.

      5. Microsoft SQL Server 2005 Compact Edition RC1 - This installs MSSQL Compact Edition. Note that there are numerous naming changes throughout the web (Mobile, Everywhere, Compact), but Compact Edition is going to be the final answer - allegedly.
      6. Windows Mobile 5.0 SDK for Pocket PC - This install will give you some more power within the IDE, e.g. it will bring up the Data Configuration Wizard to generate DataSets when adding an SDF to your project. It also installs the latest version of Northwind.sdf for you to play with. By default, it gets installed to C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Mobile\v3.0\northwind.sdf.
      7. (Semi-optional) SQL Server 2005 Compact Edition Books Online Community Technology Preview (CTP) - Reference information is always good, right?

      Additional notes:

      • You can manage an SDF file from your desktop machine, by using Server Explorer within VS.NET, or by selecting SQL Server Mobile as the Database Type in SQL Server Management Studio. On the PPC device, you can use QueryAnalyzer (located at /Program Files/SQL Mobile/EN/isqlw30.exe), or open the sdf file on the PPC device.
      • To deploy an SDF to the PPC, just add it to your solution and it will get deployed to the PPC device automatically.

      Good luck, and I hope this helps someone through the corn field maze that is CF and MSSQL CE installation.

      Thursday, December 07, 2006 8:59:00 AM (Central Standard Time, UTC-06:00)  #    Comments [0] -
      .NET | Compact Framework
      Navigation
      Archive
      <January 2007>
      SunMonTueWedThuFriSat
      31123456
      78910111213
      14151617181920
      21222324252627
      28293031123
      45678910
      About the author/Disclaimer

      Disclaimer
      The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

      © Copyright 2008
      Dan Miser
      Sign In
      Statistics
      Total Posts: 306
      This Year: 21
      This Month: 0
      This Week: 0
      Comments: 603
      All Content © 2008, Dan Miser
      DasBlog theme 'Business' created by Christoph De Baene (delarou)