Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple URL routes in WCF Rest 4.0 without trailing slash

I have a WCF REST 4.0 project based on the the WCF REST Service Template 40(CS). I'd like to expose simple service endpoint URLs without trailing slashes. For example:

  1. CarService.cs
    • http://www.domain.com/cars - GET returns a list of all cars
    • http://www.domain.com/cars/123 - GET returns a single car with ID 123
  2. TruckService.cs
    • http://www.domain.com/trucks - GET returns a list of all trucks
    • http://www.domain.com/trucks/456 - GET returns a single truck with ID 456

I look at the above URLs as resource requests (not directories), which is why I don't think trailing slashes are appropriate here.

Unfortunately, I can't seem to get the behavior I want because I am always redirected to /cars/ and /trucks/ with a trailing slash.

Here's how I've defined the "cars" route and service method - note that I have not included any slashes in any of the route or URI template definitions:

// Global.asax.cs
RouteTable.Routes.Add(new ServiceRoute("cars", new WebServiceHostFactory(), typeof(CarService)));

// CarService.cs
[WebGet(UriTemplate = "")]
public List<Car> GetCollection()
{
    return DataContext.GetAllCars();
}

Note that MVC does not work this way. With the MapRoute method I can route requests directly to http://www.domain.com/about without a redirect to /about/. How can I get the same behavior in WCF REST 4.0?

like image 883
Will Avatar asked Oct 19 '10 17:10

Will


People also ask

Do URLs need a trailing slash?

Historically, a trailing slash marked a directory and a URL without a trailing slash at the end used to mean that the URL was a file. Today, however, trailing slashes are purely conventional, and Google does not care whether you use them; as long as you're consistent.

Why do some URLs have a trailing slash?

A trailing slash is a forward slash placed at the end of a URL. It's usually used to indicate a directory (as opposed to a file), but in SEO it can affect your rankings. Take a look at the URLs below and guess which one is 'correct'. Note that one of them has a trailing slash at the end.


1 Answers

The primary issue that you're running into is that the current version of WCF REST causes a 307 redirect (to the "/") when you have an empty string for the UriTemplate in your WebGet attribute. As far as I know, there is no getting around this in the current version.

However, there are a couple of "middle ground" solution to your problem given that you want a solution that 1) allows you to differentiate services, and 2) have (relatively) short URIs.

First Solution You can put this in your global.asax file (per this example). You can do a service route for each service:

RouteTable.Routes.Add(new ServiceRoute("cars", new WebServiceHostFactory(), typeof(CarService)));
RouteTable.Routes.Add(new ServiceRoute("trucks", new WebServiceHostFactory(), typeof(TruckService)));

At this point you can populate your UriTemplate in each service:

[WebGet(UriTemplate = "all")]
CarPool GetAllCars();

[WebGet(UriTemplate = "{carName}")]
Car GetCar(string carName);

This will allow you URIs of:

www.domain.com/cars/all
www.domain.com/cars/123 or www.domain.com/cars/honda

similarly for trucks:

www.domain.com/trucks/all
www.domain.com/trucks/123 or www.domain.com/trucks/ford

Second Solution Use the service host from the REST Starter Kit (i.e., the WebServiceHost2Factory).

RouteTable.Routes.Add(new ServiceRoute("cars", new WebServiceHost2Factory(), typeof(CarService)));

This does not result in a 307 redirect when using the URIs that you're attempting to use above and thus, gives you exactly what you need. Though I realize that feels a little weird using that service host factory rather than the one that ships with WCF 4.

like image 106
Steve Michelotti Avatar answered Sep 19 '22 20:09

Steve Michelotti