1

I have following code

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
config.Formatters.JsonFormatter.MediaTypeMappings.Add(
    new UriPathExtensionMapping("json", "application/json"));
config.Formatters.XmlFormatter.MediaTypeMappings.Add(
    new UriPathExtensionMapping("xml", "application/xml"));

Now I want if some one does not provide extension in api like http://apuUrl/getBooks it should return by default JSON value.

My following scenarios are working fine:

http://apuUrl/getBooks.json -> returns JSON

http://apuUrl/getBooks.xml -> returns XML

Note: I don't want to make extra routing for every API

DavidG
  • 113,891
  • 12
  • 217
  • 223
Md. Parvez Alam
  • 4,326
  • 5
  • 48
  • 108

1 Answers1

2

How about using a DelegatingHandler to override the acceptheader?

public class MediaTypeDelegatingHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var url = request.RequestUri.ToString();
        //TODO: Maybe a more elegant check?
        if (url.EndsWith(".json"))
        {
            // clear the accept and replace it to use JSON.
            request.Headers.Accept.Clear();
            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        }
        else if (url.EndsWith(".xml"))
        {
            request.Headers.Accept.Clear();
            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
        }
        return await base.SendAsync(request, cancellationToken);
    }
}

And in your configuration:

GlobalConfiguration.Configuration.MessageHandlers.Add(new MediaTypeDelegatingHandler());

And your controller:

public class FooController : ApiController
{
    public string Get()
    {
        return "test";
    }
}

And if you go to http://yoursite.com/api/Foo/?.json should return:

"test"

While http://yoursite.com/api/Foo/?.xml should return

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">test</string>

Edit: Note that you still need to handle the route parameter input, since the controller doesn't expect the .json-parameter. That's why the ? may be necessary.

smoksnes
  • 10,509
  • 4
  • 49
  • 74