Microsoft MVP: ASP.NET/IIS Awarded; Again!

image

Microsoft once again has chosen to award me with the MVP Award for ASP.NET/IIS.  Once again I find myself very honored and humbled to be recognized for my efforts in the community.  I have always said that even if I am not an MVP I will continue to go out and foster community wherever I can, and I will, but not just yet.

I want to thank the Northwest Arkansas Technical community, hey they have to put up with me Winking smile.  They have been a great source of ideas and inspiration and I would go to bat for any of you.  Thanks for listening to me rant, and for sometimes telling me to shut up Smile.

Thanks again to Microsoft for the honor of being an MVP and thanks to the community for helping me get there.

Configuration File Transformations for All with SlowCheetah

When I first saw that ability in Visual Studio 2010 to transform web.config files for the target platform I was very excited.  This was a real deployment issue solved for me.  Over were the writing code that was environment aware, an maintaining multiple config files; one for each environment and swapping them out at deploy time.

The main thing that disappointed me was that it only worked on web project.  This was a real problem for other project types too.

Today I squealed like a little girl when I read SlowCheetah - Web.config Transformation Syntax now generalized for any XML configuration file on Scott Hanselman’s blog.

SlowCheeta - XML Tranforms is a Visual Studio extension that bring configuration file transformations to any xml file.  I have downloaded and installed it and will be following Scott’s excellent post to learn more about it. 

The Holy Grail of maintaining your configuration files has been achieved!

Turn Off Feed Read Preview to Show XML in Internet Explorer

Last night I was creating a sample application to demonstrate how to add OData to an ASP.NET MVC application.  Every time I went to the URL in Internet Explorer (IE9) it kept showing the xml with the RSS style sheet. 

Here is what you see:

image

This is not what I want to see.  I searched for a couple of hours on how to turn that off and nothing.  Finally, this morning I just started diving through the Internet Explorer settings and finally found it.

To force Internet Explorer to display the XML instead of the stylized view do the following:

  • Open Tools->Internet Options
  • Select the Content tab
  • Click the “Settings” button in the Feed and Web slices section
  • Uncheck Turn on feed reading view
  • Click “OK” to save the settings

Here is what you see know:

image

This makes it much easier to make sure I am getting what I expected in the xml return.  I don’t use any browser for reading my RSS feeds and have always found it annoying that it kept trying to show me the xml in a format I didn’t want to see.  Know I see the XML, gravy!

Real Simple Discovery Made Easy with the JaySmith.RealSimpleDiscovery Library

Recently I have been spending a lot of time writing blog features for several applications I am working on.  I always have to wire up some of the same handlers for exposing API endpoints for services such as MetaWeblogAPI, Blogger, LiveJournal, etc.  So, being the lazy coder that I am I started looking at ways to make them easier to share between projects. 

In this post I am going to cover a configuration based approach I have developed for handing the first step in exposing those services, Real Simple Discovery.

Real Simple Discovery as described from the RFC posted here is as follows:

Really Simple Discovery is a way to help client software find the services needed to read, edit, or "work with" weblogging software.  Although I talk about weblogging software, there's no reason this format can't apply to other forms of web client/system software that I wasn't considering, or may not even exist as of this writing.  This format is simple but flexible. One of the design goals was to ensure that it would be human writeable. This was my "test" for ensuring that the format was easy for everyone to implement.

What is the benefit of using a handler versus just putting it in an rsd.xml file at your web root?

If you are creating a simple site that is for a single URL and will never be used by others then using an rsd.xml file is an ideal solution.  On the other hand, if you are creating a project that you expect others to install on their own domain they will have to modify the rsd.xml file to provide the full URL to each handler.  This is something you would expect a developer to know how to do but not someone who has just download your code and installed it.  They expect to deploy and it just to run.

Dynamically generating this information allows for a zero config setup where the code that generates the XML can figure out the correct URL’s to provide without the need of manual configuration.  The developer sets up the protocols they want to implement in the web.config file and the real simple discovery handler generates the xml based on that config.  In this scenario the user of the site does not have to setup anything to get it to work

Example rsd.xml from my blog using Blogengine.NET

  <rsd version="1.0">
  <service>
    <engineName>BlogEngine.NET 1.6.1.0</engineName>
    <engineLink>http://dotnetblogengine.com</engineLink>
    <homePageLink>http://jaysmith.us/</homePageLink>
    <apis>
      <api name="MetaWeblog" preferred="true" apiLink="http://jaysmith.us/metaweblog.axd" blogID="http://jaysmith.us/"/>
      <api name="BlogML" preferred="false" apiLink="http://jaysmith.us/api/BlogImporter.asmx" blogID="http://jaysmith.us/"/>
    </apis>
  </service>
</rsd>

Installing JaySmith.RealSimpleDisovery via NuGet

This approach will work for both WebForms and MVC applications since it uses a handler to basically bypass the UI layer.

Example of the config

<realSimpleDiscovery>
    <apis>
      <add name="Atom" preferred="false" apiLink="atom.axd" />
      <add name="Blogger" preferred="false" apiLink="blogger.axd" />
      <add name="MetaWeblog" preferred="true" apiLink="metaweblog.axd" />
      <add name="Manila" preferred="false" apiLink="manila.axd" />
      <add name="MetaWiki" preferred="false" apiLink="metawiki.axd" />
      <add name="LiveJournal" preferred="false" apiLink="livejournal.axd" />
    </apis>
</realSimpleDiscovery>

Navigating to http://[MyHost]/rsd.axd will display the following:

<?xml version="1.0" encoding="utf-8" ?> 
<rsd version="1.0">
  <service>
    <engineName>JaySmith.RealSimpleDiscovery Engine v1.0</engineName> 
    <engineLink>https://github.com/JaySmith/RealSimpleDiscovery</engineLink> 
    <homePageLink>http://localhost:4104/</homePageLink> 
    <apis>
      <api name="MetaWeblog" preferred="True" apiLink="http://localhost:4104/metaweblog.axd" blogID="http://localhost:4104/" /> 
      <api name="Atom" preferred="False" apiLink="http://localhost:4104/atom.axd" blogID="http://localhost:4104/" /> 
      <api name="Blogger" preferred="False" apiLink="http://localhost:4104/blogger.axd" blogID="http://localhost:4104/" /> 
      <api name="Manila" preferred="False" apiLink="http://localhost:4104/manila.axd" blogID="http://localhost:4104/" /> 
      <api name="MetaWiki" preferred="False" apiLink="http://localhost:4104/metawiki.axd" blogID="http://localhost:4104/" /> 
      <api name="LiveJournal" preferred="False" apiLink="http://localhost:4104/livejournal.axd" blogID="http://localhost:4104/" /> 
    </apis>
  </service>
</rsd>

Another feature is that the implementation is flexible enough to handle new APIs as they become available.  To expose a new api all you have to do is add it to the web.config file and the end point of the new api will be generated just like all the rest.

Example of new API

  <realSimpleDiscovery>
    <apis>
      <add name="Atom" preferred="false" apiLink="atom.axd" />
      <add name="Blogger" preferred="false" apiLink="blogger.axd" />
      <add name="MetaWeblog" preferred="true" apiLink="metaweblog.axd" />
      <add name="Manila" preferred="false" apiLink="manila.axd" />
      <add name="MetaWiki" preferred="false" apiLink="metawiki.axd" />
      <add name="LiveJournal" preferred="false" apiLink="/api/livejournal.axd" />
      <add name="MyNewApi" preferred="false" apiLink="/mynewapi.axd" />
    </apis>
  </realSimpleDiscovery>

Output with new API after navigation to http://[myhost]/rsd.axd

<?xml version="1.0" encoding="utf-8" ?> 
<rsd version="1.0">
<service>
  <engineName>JaySmith.RealSimpleDiscovery Engine v1.0</engineName> 
  <engineLink>https://github.com/JaySmith/RealSimpleDiscovery</engineLink> 
  <homePageLink>http://localhost:4104/</homePageLink> 
 <apis>
  <api name="MetaWeblog" preferred="True" apiLink="http://localhost:4104/metaweblog.axd" blogID="http://localhost:4104/" /> 
  <api name="Atom" preferred="False" apiLink="http://localhost:4104/atom.axd" blogID="http://localhost:4104/" /> 
  <api name="Blogger" preferred="False" apiLink="http://localhost:4104/blogger.axd" blogID="http://localhost:4104/" /> 
  <api name="Manila" preferred="False" apiLink="http://localhost:4104/manila.axd" blogID="http://localhost:4104/" /> 
  <api name="MetaWiki" preferred="False" apiLink="http://localhost:4104/metawiki.axd" blogID="http://localhost:4104/" /> 
  <api name="LiveJournal" preferred="False" apiLink="http://localhost:4104/api/livejournal.axd" blogID="http://localhost:4104/" /> 
  <api name="MyNewApi" preferred="False" apiLink="http://localhost:4104/mynewapi.axd" blogID="http://localhost:4104/" /> 
  </apis>
 </service>
</rsd>

You can see that the new MyNewApi endpoint has been included.

Looking for feedback

I am really looking for feedback on this approach so if you are creating applications that need to use Real Simple Discovery please give this a test drive and let me know of any improvements you would like to see.

Resources on Real Simple Discovery:

RFC: Really Simple Discoverability 1.0

http://archipelago.phrasewise.com/display?page=oldsite/1330.html

http://cyber.law.harvard.edu/blogs/gems/tech/rsd.html

Generic Repository for Entity Framework

I have started trying to learn how to leverage the Entity Framework for a the re-write of the GiveCamp Starter Site and wanted to implement a generic repository for data access like I use on most of my projects.  I started with the example given by Mikael Henriksson’s Post Generic Repository for Entity Framework for Pluralized Entity Set.  I modified it to fit my standard Repository interface and took the liberty of simplifying it in a few places.

I have run this through several test and haven’t found any issues. I would love those with a critical eye to give this a look over and let me know if I am missing anything.

The IRepository Interface

public interface IRepository : IDisposable
  {
    T Get<T>(int id) where T : IEntityWithKey;
    T Get<T>(Expression<Func<T, bool>> predicate) where T : IEntityWithKey;
    IQueryable<T> Find<T>(Expression<Func<T, bool>> predicate) where T : IEntityWithKey; 
    T Save<T>(T entity) where T : IEntityWithKey;
    T Delete<T>(T entity) where T : IEntityWithKey;
  }

I did use the ObjectContextExtensions from Mikael’s post because they did such a good job of solving the issue of getting the EntitySetName. I am not going go into a lot of detail explaining what is going on because a feel the class pretty much explains itself.

The Repository Class:

public class EntityFrameworkRepository : IRepository   
{
  private readonly ObjectContext context;
  public EntityFrameworkRepository()
  {
    context = new WmdDemoEntities();
  }
  public EntityFrameworkRepository(ObjectContext entityContext)
  {
    context = entityContext;
  }
  public T Get<T>(int id) where T : IEntityWithKey
  {
    IEnumerable<KeyValuePair<string, object>> entityKeyValues = new[] { new KeyValuePair<string, object>("Id", id) };
    var key = new EntityKey(context.GetEntitySet<T>().Name, entityKeyValues);
    
    return (T)context.GetObjectByKey(key);
  }
  public T Get<T>(Expression<Func<T, bool>> predicate) where T : IEntityWithKey
  {
    return context.CreateQuery<T>("[" + context.GetEntitySet<T>().Name + "]")
      .Where(predicate)
      .FirstOrDefault();
  }
  public IQueryable<T> Find<T>(Expression<Func<T, bool>> predicate) where T : IEntityWithKey
  {
    return context
      .CreateQuery<T>("[" + context.GetEntitySet<T>().Name + "]")
      .Where(predicate);
  }
  
  public T Save<T>(T entity) where T : IEntityWithKey
  {
    object originalItem;
    
    if (context.TryGetObjectByKey(entity.EntityKey, out originalItem))
      context.ApplyPropertyChanges(entity.EntityKey.EntitySetName, entity); 
    else
      context.AddObject(entity.EntityKey.EntitySetName, entity);
      
    context.SaveChanges();
    
    return entity;
  }
  public T Delete<T>(T entity) where T : IEntityWithKey
  {
    context.DeleteObject(entity);
    context.SaveChanges();
    
    return entity;
  }
  
  public void Dispose()
  {
    context.Dispose();
  }
}
   

Here is an example of usage in a console application

class Program
{
  static void Main(string[] args)
  {
    IRepository repository = new EntityFrameworkRepository();
    
    var page = repository.Get<Page>(x => x.PageId == 1);
    Console.WriteLine("Title: {0}", page.Title);
    Console.WriteLine("Content: {0}", page.Content);
  
    repository.Dispose();
  
    Console.ReadLine();
  }
}

I love taking this approach to persistence because it is so flexible and allows me to swap out repository implementations with little issue.

Again love to hear some feedback on this approach.