How to get ASP.NET Web API to return JSON instead of XML using Chrome?

Note: Read the comments of this answer, it can produce a XSS Vulnerability if you are using the default error handing of WebAPI

I just add the following in App_Start / WebApiConfig.cs class in my MVC Web API project.

config.Formatters.JsonFormatter.SupportedMediaTypes
    .Add(new MediaTypeHeaderValue("text/html") );

That makes sure you get JSON on most queries, but you can get XML when you send text/xml.

NameSpace is using System.Net.Http.Headers.

If you do this in the WebApiConfig you will get JSON by default, but it will still allow you to return XML if you pass text/xml as the request Accept header.

Note: This removes the support for application/xml

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
        config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
    }
}

Using RequestHeaderMapping works even better, because it also sets the Content-Type = application/json in the response header, which allows Firefox (with JSONView add-on) to format the response as JSON.

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings
.Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept", 
                              "text/html",
                              StringComparison.InvariantCultureIgnoreCase,
                              true, 
                              "application/json"));

MVC4 Quick Tip #3–Removing the XML Formatter from ASP.Net Web API

In Global.asax add the line:

GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

like so:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    BundleTable.Bundles.RegisterTemplateBundles();
    GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
}

Answer #3:

One quick option is to use the MediaTypeMapping specialization. Here is an example of using QueryStringMapping in the Application_Start event:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("a", "b", "application/json"));

Now whenever the url contains the querystring ?a=b in this case, Json response will be shown in the browser.

Don’t use your browser to test your API.

Instead, try to use an HTTP client that allows you to specify your requests, such as CURL, or even Fiddler.

The problem with this issue is in the client, not in the API. The web API behaves correctly, according to the browser’s request.

Most of the above answers makes perfect sense. Since you are seeing data being formatted in XML format ,that means XML formatter is applied,SO you can see JSON format just by removing the XMLFormatter from the HttpConfiguration parameter like

public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );                
            config.Formatters.Remove(config.Formatters.XmlFormatter);                
            config.EnableSystemDiagnosticsTracing();
        }

since JSON is the default format

Answer #5:

I used a global action filter to remove Accept: application/xml when the User-Agent header contains “Chrome”:

internal class RemoveXmlForGoogleChromeFilter : IActionFilter
{
    public bool AllowMultiple
    {
        get { return false; }
    }

    public async Task<HttpResponseMessage> ExecuteActionFilterAsync(
        HttpActionContext actionContext,
        CancellationToken cancellationToken,
        Func<Task<HttpResponseMessage>> continuation)
    {
        var userAgent = actionContext.Request.Headers.UserAgent.ToString();
        if (userAgent.Contains("Chrome"))
        {
            var acceptHeaders = actionContext.Request.Headers.Accept;
            var header =
                acceptHeaders.SingleOrDefault(
                    x => x.MediaType.Contains("application/xml"));
            acceptHeaders.Remove(header);
        }

        return await continuation();
    }
}

Seems to work.

Answer #6:

Returning the correct format is done by the media-type formatter. As others mentioned, you can do this in the WebApiConfig class:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        ...

        // Configure Web API to return JSON
        config.Formatters.JsonFormatter
        .SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));

        ...
    }
}

In case your actions are returning XML (which is the case by default) and you need just a specific method to return JSON, you can then use an ActionFilterAttribute and apply it to that specific action.

Filter attribute:

public class JsonOutputAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        ObjectContent content = actionExecutedContext.Response.Content as ObjectContent;
        var value = content.Value;
        Type targetType = actionExecutedContext.Response.Content.GetType().GetGenericArguments()[0];

        var httpResponseMsg = new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.OK,
            RequestMessage = actionExecutedContext.Request,
            Content = new ObjectContent(targetType, value, new JsonMediaTypeFormatter(), (string)null)
        };

        actionExecutedContext.Response = httpResponseMsg;
        base.OnActionExecuted(actionExecutedContext);
    }
}

Applying to action:

[JsonOutput]
public IEnumerable<Person> GetPersons()
{
    return _repository.AllPersons(); // the returned output will be in JSON
}

Note that you can omit the word Attribute on the action decoration and use just [JsonOutput] instead of [JsonOutputAttribute].

Answer #7:

It’s unclear to me why there is all of this complexity in the answer. Sure there are lots of ways you can do this, with QueryStrings, headers and options… but what I believe to be the best practice is simple. You request a plain URL (ex: http://yourstartup.com/api/cars) and in return you get JSON. You get JSON with the proper response header:

Content-Type: application/json

In looking for an answer to this very same question, I found this thread, and had to keep going because this accepted answer doesn’t work exactly.

I’ll add my tip here as well.

WebApiConfig.cs

namespace com.yourstartup
{
  using ...;
  using System.Net.Http.Formatting;
  ...
  config.Formatters.Clear(); //because there are defaults of XML..
  config.Formatters.Add(new JsonMediaTypeFormatter());
}

I do have a question of where the defaults (at least the ones I am seeing) come from. Are they .NET defaults, or perhaps created somewhere else (by someone else on my project). Anways, hope this helps.

Hope you learned something from this post.

Follow Programming Articles for more!

About ᴾᴿᴼᵍʳᵃᵐᵐᵉʳ

Linux and Python enthusiast, in love with open source since 2014, Writer at programming-articles.com, India.

View all posts by ᴾᴿᴼᵍʳᵃᵐᵐᵉʳ →