In this post I want to get a basic web service up and running. I’ll start off simple with a read only feature. Many database backed .Net applications use GUIDs as identifiers for their entities. Unfortunately, a number of client technologies cannot generate truly unique identifiers, for instance Flash based clients. Two possible solutions are:
- Replace any “GUIDs” supplied by clients with real ones;
- Provide a way for those clients to obtain genuine GUIDs.
For this exercise I will create a service that allows a client to download up to a 100 GUIDs at a time which it can then cache and use as required. I started by installing Visual Studio 2008 SP1 and the ASP.Net MVC Preview 5. MVC installs some new project templates. I used the ASP.NET MVC Web Application template to create a standard project. I stared out by adding the following files:
- GuidController.cs was added to the Controller folder;
- GuidGenerator.cs was added to a newly created Model\Guid folder;
- Guid.aspx was added to a newly created View\Guid folder
In the initial version, GuidGenerator.cs had a single method which created a list of new GUIDs:
public static List<System.Guid> GenerateGuids(int count)
{
List<System.Guid> result = new List<System.Guid>();
for (int counter = 0; counter < count; counter++)
{
result.Add(System.Guid.NewGuid());
}
return result;
}
The Guid controller called the model and passed the results to the Guid.aspx view:
public ActionResult Index(int? count)
{
// Provide a default count and restrict to the range 1 - 100
int actualCount = count ?? 10;
actualCount = Math.Min(100, actualCount);
actualCount = actualCount >= 1 ? actualCount : 1;
// Generate the requested Guids
List<Guid> guidGeneratorResult = GuidGenerator.GenerateGuids(actualCount);
// Guids should be different every time some this is one result we don't want to cache
this.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
return View("Guid", guidGeneratorResult);
}
The aspx page does little more than loop over the list of Guids, adding each one as an item in an unordered list:
<asp:Content ID="MainContent" ContentPlaceHolderID="MainContent" runat="server">
<ul class="guids">
<% foreach (var guid in ViewData.Model)
{ %>
<li><%= guid.ToString().ToUpper() %></li>
<% } %>
</ul>
</asp:Content>
Update 29 Jan 2009: In the above snippet I have changed ViewData.Model.Guids to ViewData.Model, the snippet was originally taken from the code for a later post so wouldn’t work. Also, since ASP.Net RC1, it is possible to remove “ViewData.” as well.
After building the project I could point my browser at:
http://localhost/RESTfulMVCWebService/Guid
and I see a list of GUIDs. Changing the URI to:
http://localhost/RESTfulMVCWebService/Guid?count=15
returns a longer list. So there you go… if you followed my steps above, you’ve created a RESTful web service using ASP.Net and MVC.
Some people may feel a little cheated by now… all I’ve done is create a normal MVC web page, using nothing but the default features… I haven’t even changed the routing table entries! For those people, think again. It doesn’t have to be a browser that uses the above URIs. From JavaScript, the XMLHttpRequest object could make the same call and what it would retrieve is XHTML, a snippet of which is below:
<ul class="guids">
<li>FFD19FE8-5CBD-492E-BE1C-F74BDE950705</li>
<li>23A59FC4-3402-4053-BB3B-5D8C9E913188</li>
<li>CD078B90-FD24-4C6A-A1B4-C3E350737C79</li>
<li>7573F035-F6DF-4001-A73B-A9B0A6380EDC</li>
<li>0C04B661-301D-4BB3-A867-205101B116E2</li>
<li>FBA6346E-D779-4CCB-A0FE-34DEE65BB8E3</li>
<li>5A39D1C5-E7CC-458B-98A4-83A458496B7B</li>
<li>CA0F400A-8567-4C76-98AD-7E49A558E3B1</li>
<li>965A0621-1EE0-419F-8BD2-CF479CAE6C3D</li>
<li>D87DA5E3-5B9F-437C-B876-32ADF8B44A98</li>
</ul>
This XHTML could be loaded into an Xml parser and the GUIDs extracted very easily.
XHTML is a valid representation to return from a web service. In fact, in their book RESTful Web Services, Leonard Richardson and Sam Ruby describe why XHTML is their preferred representation. They argue that, whilst most web services return a custom XML vocabulary, it is usually not necessary. It is often better to reuse an existing standard, especially if it is widely adopted. XHTML has a very well known way to represent a list, so why not reuse it?
OK, so if I left it there, I think you could be justifiably disappointed. So my next post will start doing some real work… I’ll describe my framework for supporting multiple representations.