REST in ASP.NET MVC – Generating XML

Nowadays I have a hobby project – a beer catalog for mobile devices. It sounds pretty simple, but I managed to make it complex – and robust as well.
The solution has three parts: an ASP.NET MVC web site backed up by SQL Server, an iPhone and an Android client. I struggled a lot with WCF, I thought it would be the right way to implement a REST-based service, but couldn’t figure it out myself. Anyway, I had an MVC site up and running, so I thought I can sort this out pretty easy, since I had an object model with five entities – that means five services to the mobile apps.
I’ll write about the mobile clients in a future post. It’s enough to know that they pull the data from the services and store it in their own SQLite 3 databases. Sometimes (maybe once a week) they perform an update, request the data again and overwrite their existing databases – that’s all that there’s relevant now.
So how would you create a REST API in ASP.NET MVC. I felt that I want something terribly simple. I want to say that return this data as XML, without any duplication. The obvious way was to subclass ActionResult. After some inspiration from William Duffy’s RSSResult implementation, I came up with the following code:

    1. public class XMLResult<T> : ActionResult
    2.   {
    3.     private IEnumerable<T> _items;
    4.     private string _rootName;
    5.     private string _typeName;
    6.     public XMLResult(IEnumerable<T> items, string rootName, string typeName)
    7.     {
    8.       _items = items;
    9.       _rootName = rootName;
    10.       _typeName = typeName;
    11.     }
    12.     public override void ExecuteResult(ControllerContext context)
    13.     {
    14.       if (_items == null)
    15.       {
    16.         throw new NullReferenceException();
    17.       }
    18.       XmlWriterSettings settings = new XmlWriterSettings() { Indent = true, NewLineHandling = NewLineHandling.Entitize };
    19.       context.HttpContext.Response.ContentType = “text/xml”;
    20.       using (XmlWriter writer = XmlWriter.Create(context.HttpContext.Response.OutputStream, settings))
    21.       {
    22.         writer.WriteStartElement(_rootName);
    23.         foreach (T item in _items)
    24.         {
    25.           if (string.IsNullOrEmpty(_typeName))
    26.           {
    27.             writer.WriteStartElement(item.GetType().Name);
    28.           }
    29.           else
    30.           {
    31.             writer.WriteStartElement(_typeName);
    32.           }
    33.           foreach (PropertyInfo pi in item.GetType().GetProperties())
    34.           {
    35.             if (pi.PropertyType.IsValueType || pi.PropertyType == typeof(string))
    36.             {
    37.               if (pi.GetValue(item, null) != null)
    38.               {
    39.                 writer.WriteElementString(pi.Name, pi.GetValue(item, null).ToString());
    40.               }
    41.             }
    42.           }
    43.           writer.WriteEndElement();
    44.         }
    45.         writer.WriteEndElement();
    46.       }
    47.     }
    48.   }

* This source code was highlighted with Source Code Highlighter.

I think it speaks for itself. The only thing needs a little explanation is the narrowing of the types in the PropertyInfo loop. I needed only value types and string, nothing else. Since my entities contained BLOB data and navigation properties, I got rid of the rest.
This little class is used as follows:

    1. public XMLResult<Beer> Beers()
    2.     {
    3.       return new XMLResult<Beer>(context.Beers.Where(x=>x.IsApproved.Value).OrderBy(x=>x.Name), “Beers”, “Beer”);
    4.     }

* This source code was highlighted with Source Code Highlighter.

And it works with basically anything, thanks to the generic type parameter. From this startpoint, you can easily implement your own POX (Plain Old XML) services with ASP.NET MVC. In the next post we consider how to extract the entities from the generated XML on the iPhone.

Manage XML Data

This objective may include, but is not limited to: XML datatype, XML indexes, XML schema collections

When you want to work with XML data in SQL Server, you have the xml data type at hand. This one has some useful functions to query and modify XML data, but more of this later. There are two types of the xml data type, namely untyped and typed. The difference is that you can use an XML schema to enforce rules when working with typed xml.

To create an XML schema in SQL Server, you use the CREATE XML SCHEMA COLLECTION order. This looks as follows:

CREATE XML SCHEMA COLLECTION MyOwnSchema
AS N’<?xml version=”1.0” encoding=”utf-16” ?>
<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema/”>
 <xsd:element name=”Person”>
   <xsd:complexType>
    <xsd:sequence>
     <xsd:element name=”FirstName” type=”xsd:string” />
     <xsd:element name=”LastName” type=”xsd:string” />
    </xsd:sequence>
   </xsd:complexType>
  </xsd:element>
</xsd:schema>

Now you can enforce the validity of any XML you create against this schema by declaring an xml type as follows:
Continue reading “Manage XML Data”

Transform XML data into relational data

May include but is not limited to: OPENXML, sp_xml_preparedocument, sp_xml_removedocument

SQL Server allows you to retrieve XML data as relational data (a process known as shredding) . To implement this behavior, you’d need three methods, mentioned in the “May include but is not limited to” section, but for the sake of Google and SEO: OPENXML for the SELECT clause, the sp_xml_preparedocument  system stored procedure to prepare your documents, and the sp_xml_removedocument system stored procedure to remove the XML document from the server memory. This is essential, because your loaded XML documents will use server resources as long as the server won’t restarts, and you can easily run out of memory.

The syntax of sp_xml_preparedocument is somewhat easy. It accepts three values, and integer handle, which is an OUTPUT value, an nvarchar(max) which is the string representation of your XML document, and an optional flags parameter, which is very good, and certainly covered in SQL Server Books Online in great detail.

A simple example of using sp_xml_preparedocument:
Continue reading “Transform XML data into relational data”

Retrieve relational data as XML

May include but is not limited to: FOR XML

SQL Server has support for the XML data type for quite long time. I’m not a big fan of XML, but you are unable to evade it, especially when you work in the web business, so let’s get into it.

The question is why you’d need relational data in an XML format. One good answer (among thousand possible candidates) is interoperability. XML is well understood, and is everywhere, so having data in this format definitely makes sense.

This objective covers the FOR XML clause, which you can append to your SELECT clauses to retrieve and control the format of your data. FOR XML has the following options:

  • RAW: each row of the data is represented as a single node, and the columns as attributes. However, you can fine-tune this behavior.
  • AUTO: similar to RAW, but default node name for each row is the name of the table (and not the generic “row”).
  • PATH: enables you to format your result with XPath specified as the column alias.
  • EXPLICIT: provides the finest grain of control, you can define the layout of your XML document in a syntax similar to XPath. The notation is: ColumnName AS [ElementName!TagNumber!AttributeName!Directive].

Continue reading “Retrieve relational data as XML”

XML Serialization

As its name suggests, XML serialization is the process of serializing an object into XML format. Quite luckily, the format of the XML file can be massively customized, so be prepared for dumb questions, like which XML file well be the output of this code, or the reverse (even better).

The classes of XML serialization lives in the System.Xml.Serialization namespace. No reference needed, because this namespace is part of the System.Xml.dll, which is linked by Visual Studio for every project.

The main class here is XmlSerializer. Now this class has absolutely nothing to do with the previous formatter classes. It has three useful instance methods, namely Serialize, Deserialize and CanSerialize. Yes, CanSerialize needs an XmlReader and returns true if the read XML file can be serialized by the instance. The Deserialize method is essentially the same as it was at the formatter classes, can read any kind of Stream, or Reader classes (XmlReader included!). However, the Serialize method is very different from the others. It takes a type (only include a single type when you are working with an Object-derived type with no is-a, has-a relationships), and an array of types, for  the respective is-a, has-a relationships. Yes, you need to include every single type that participates in your object’s life.

Continue reading “XML Serialization”

Read and Write XML Data

In yesterday’s posts, we examined how to retrieve and process data from a database with the help of ADO.NET. Today, we take a look at the third major area of ADO.NET: XML.

I assume that everybody got this far already met with XML, some may also become quite fond of it (shame on me, but I haven’t), so I wouldn’t waste time to introduce it. Instead let’s get see what ADO.NET has for us. In this post, I will revise the following:

  1. Processing stream-based XML
  2. Processing in-memory XML
  3. XML data binding
  4. XML and DataSet integration

I’ll not going to describe LINQ to XML, since it isn’t covered in the exam, and even when you work with LINQ to XML, you’ll still need to know the basics of ADO.NET to perform for example basic XML data binding.

Continue reading “Read and Write XML Data”