WCF REST and MVC Routing

WCF REST and MVC Routing

Recently, I was trying to add a WCF REST File Upload Service into an alpha application of mine here and was greeted by this wonderful error:

Server Error in '/' Application.

The resource cannot be found.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly.

Requested URL: /File.svc/Upload/1


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.32559

I didn't understand why I was getting the error since I had the following Operation Contract defined in my Implementation WCF File IAW [1] [2] and [3]:

      
      [OperationContract]
      [WebInvoke(Method = "POST", UriTemplate = "Upload/{Id}")]      
      string Upload(string Id, Stream fileContents);
      
      

To troubleshoot, I played around with some of the HTTPGet style Operation Contracts shown in [3] and was able to get them to work. Because of this, I first thought the problem has something to do with the fact that I was trying to use a POST operation, but I was wrong. After much goofing around, I found that an Operation Contract like the following was firing correctly:

      
      [OperationContract]
      [WebInvoke(Method = "POST", UriTemplate = "Upload/{Id}/{Junk}")]      
      string Upload(string Id, string Junk, Stream fileContents);
      
      

My unfortunate instinct was to think that this was some kind of weird REST WCF Bug but then it dawned on me that this had to be some kind of MVC Routing issue. So I looked at the Routes in my RoutingConfig.cs and found the code not much different than what one would see if she/he created a new MVC Project from the MVC Template. My code looked something like this:

      
      public static void RegisterRoutes(RouteCollection routes)
      {
         routes.IgnoreRoute("{resource}.axd/{*pathInfo}");          
         routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Inventory", action = "Index", id = UrlParameter.Optional }
         );
      }
      
      

After thinking on this for a bit, I was embarrased to realize that MVC was confusing the URL of http://localhost:50867/File.svc/Upload/1 that I was trying to use to POST to my service with an MVC Action of Upload in the File.svc Controller with an Id of 1. After comming to this embarrassing relization, I simply added an additional IgnoreRoute line to my RoutingConfig.cs file and all was well:

       
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            // Need this to keep MVC Routing from interfering with calls
            // to REST WCF Services
            routes.IgnoreRoute("{resource}.svc/{*pathInfo}");

            // Default Route Should be to the inventory Controller
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Inventory", action = "Index", id = UrlParameter.Optional }
            );
        }
      
      

The morale of the story is that it pays to be aware of the Routes you register when working with MVC. In MVC4, these Routes would normally be stored in the RoutingConfig.cs file. While I think Microsoft Tech Evangelist Jon Galloway mentions in Module 1 of [4] that programmers should try to use the default MVC routings when possible, there may be times when you need to go in and customize those routes to get the expected firing of various RESTful actions.

Bibliography

1. Kumar, Dhananjay
Uploading File to server from ASP.Net client using WCF REST Service.
debugmode.net [Online: May 1, 2011]
[Cited: October 1, 2013.]
http://debugmode.net/2011/05/01/uploading-file-to-server-from-asp-net-client-using-wcf-rest-service/

2. bendewey; jaimie
RESTful WCF service image upload problem.
StackOverflow [Online: March 20, 2009]
[Cited: October 1, 2013.]
http://stackoverflow.com/questions/664712/restful-wcf-service-image-upload-problem

3. Microsoft
WebInvokeAttribute Class.
MSDN
[Cited: October 1, 2013.]
http://msdn.microsoft.com/en-us/library/system.servicemodel.web.webinvokeattribute.aspx

4. Microsoft; Galloway, Jon; Harrison, Christopher
Developing ASP.NET MVC 4 Web Applications Jump Start
Microsoft Virtual Academy [Online: 2013]
[Cited: October 1, 2013.]
http://www.microsoftvirtualacademy.com/training-courses/developing-asp-net-mvc-4-web-applications-jump-start#fbid=edMlSP3rk7d

©2013 - Shawn Eary
This post is released under the Free Christian Document License (FCDL)