4

My config.Routes was set to:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

With this I could use:

  • localhost:port/api/products - get a full list of products
  • localhost:port/api/products/# - get a single product with the given id

Based on the browser I was getting a different format (you get XML format in FireFox and Google Chrome as default, and JSON in Internet Explorer).

I mostly need JSON, so at first I added:

var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);

so my response would always be in JSON.

Everything works as intented at this point, and I'm getting JSON-format responses on the two GET-requests mentioned above.


I then stumbled on this stackoverflow post. Thought it would be a nice feature to select for yourself which format you want to return based on the GET-request.

However, when I replace the config.Routes and JSON-only code mentioned above for:

config.Routes.MapHttpRoute(
    name: "API UriPathExtentsion",
    routeTemplate: "api/{controller}.{ext}/{id}",
    defaults: new { id = RouteParameter.Optional, ext = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
    name: "API UriPathExtension ID",
    routeTemplate: "api/{controller}/{id}.{ext}",
    defaults: new { id = RouteParameter.Optional, ext = RouteParameter.Optional }
);
config.Formatters.JsonFormatter.AddUriPathExtensionMapping("json", "application/json");
config.Formatters.XmlFormatter.AddUriPathExtensionMapping("xml", "text/xml");

I'm getting the 404 errors below:

On localhost:post/api/products: enter image description here

and on localhost:port/api/products.xml: enter image description here

Anyone know what might be wrong?

Also, I'm not sure the second piece of code will do exactly as I would like to, so here is a list of example requests and what I would like it to return:

  • localhost:port\api\products - get a list of products in default browser format
  • localhost:port\api\products\# - get a single product in default browser format
  • localhost:port\api\products.xml - get a list of products in XML format
  • localhost:port\api\products.json - get a list of products in JSON format
  • localhost:port\api\products\#.xml - get a single product in XML format
  • localhost:port\api\products\#.json - get a single product in JSON format

Thanks in advance for the responses.


Edit 1: Changed exten to ext after a comment. Still the same errors..

Community
  • 1
  • 1
Kevin Cruijssen
  • 9,153
  • 9
  • 61
  • 135
  • The answer in the post you link to includes [this comment](http://stackoverflow.com/questions/13053485/return-either-xml-or-json-from-mvc-web-api-based-on-request#comment19002795_13053629)... does this help? –  Apr 29 '14 at 14:01
  • @DaveParsons not really, since I already use `exten` instead of `extension`, as seen in the code of my main-post. – Kevin Cruijssen Apr 29 '14 at 14:10
  • The comment says to use `{ext}` not `{exten}`. –  Apr 29 '14 at 14:11
  • @DaveParsons I've changed it to `{ext}` now, but still the same errors.. – Kevin Cruijssen Apr 29 '14 at 14:36
  • Don't you need to keep your original route to get `/api/products` to work? – Halvard Apr 29 '14 at 14:59
  • 1
    Also, from your linked post: **Remember in this example, you still have to issue the request with the appropriate content-type.** Have you done this? – Halvard Apr 29 '14 at 15:05
  • @Halvard ok, I missed that.. I'm kinda new to Web APIs though, so where do I add these content-types? I've looked at the link's example project, but he literally added beforeSend ajax functions with hardcoded localhost-links, this obviously isn't what I want. Could you perhaps make a sample post of how I can make a dynamically content-type request header? – Kevin Cruijssen Apr 30 '14 at 07:23
  • My answer was too long for a comment so I chanced putting it as an answer. I hope it helps! – Halvard Apr 30 '14 at 15:40

1 Answers1

3

The post you linked to says:

Remember in this example, you still have to issue the request with the appropriate content-type.

This means that whoever calls your API need to set the content-type to match either application/json or text/xml. If you are calling from a browser your content-type will be the default content-type of the browser you are using, which might easily be text/plain.

Option 1: Google and find out how to change the content-type of the browser you are using. I have never tried to change this myself.

Option 2: If you call this from code and use C#, use the HttpClient and modify the content-type before your call as explained in this StackOverflow post.

Option 3: Use the composer in Fiddler (free) to call your service. There it is easy to set the content-type. I prefer this when testing web APIs.

When all this is said and done, I'm not sure this actually solves your problem, but I hope so. At least you then follow everything the post you linked to says. Good luck!

Community
  • 1
  • 1
Halvard
  • 3,891
  • 6
  • 39
  • 51
  • 3
    +1 - also an option is the Advanced Rest Client for google chrome that allows you to explicitly set all headers, and nicely formats JSON results. – Moo-Juice Apr 30 '14 at 15:43