44

Currently, my ApiControllers are returning XML as a response, but for a single method, I want to return JSON. i.e. I can't make a global change to force responses as JSON.

public class CarController : ApiController
{  
    [System.Web.Mvc.Route("api/Player/videos")]
    public HttpResponseMessage GetVideoMappings()
    {
        var model = new MyCarModel();    
        return model;
    }
}

I tried doing this, but can't seem to convert my model to a JSON string correctly:

var jsonString = Json(model).ToString();    
var response = this.Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(jsonString, Encoding.UTF8, "application/json");
return response;
Ashiquzzaman
  • 5,129
  • 3
  • 27
  • 38
cool breeze
  • 4,461
  • 5
  • 38
  • 67
  • 1
    Try the return type `JsonResult` instead of `HttpResponseMessage`, then you can return a `Json` object, like this: `return Json(model)` – Ricardo Pontual Mar 02 '18 at 16:53
  • try this [ApiController.Ok](https://msdn.microsoft.com/en-us/library/system.web.http.apicontroller.ok%28v=vs.118%29.aspx?f=255&MSPPError=-2147217396) you just do `return Ok(model)` – Mohammad Ali Mar 02 '18 at 16:56
  • @RicardoPontual is it a System.Web.Mvc.JsonResult? I'm getting a ```Cannot implicitly convert type 'System.Web.Http.Results.JsonResult' to 'System.Web.Mvc.JsonResult' ``` – cool breeze Mar 02 '18 at 17:00
  • 1
    `System.Web.Mvc.JsonResult`, if your classe inherits from `System.Web.Mvc.Controller`, or you can maintain the `HttpResponseMessage` and use `return Request.CreateResponse(HttpStatusCode.OK, model)` – Ricardo Pontual Mar 02 '18 at 17:22

5 Answers5

75

If you can't make a global change to force responses as JSON, then try:

[Route("api/Player/videos")]
public HttpResponseMessage GetVideoMappings()
{
    var model = new MyCarModel();
    return Request.CreateResponse(HttpStatusCode.OK,model,Configuration.Formatters.JsonFormatter);
}

OR

[Route("api/Player/videos")]
public IHttpActionResult GetVideoMappings()
{
    var model = new MyCarModel();
    return Json(model);    
}

If you want to change globally, then first go to YourProject/App_Start/WebApiConfig.cs and add:

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

at the bottom of the Register method.

Then try:

[Route("api/Player/videos")]
public IHttpActionResult GetVideoMappings()
{
    var model = new MyCarModel();
    return Ok(model);    
}
Ashiquzzaman
  • 5,129
  • 3
  • 27
  • 38
7

The XML is returned instead JSON because the caller is requesting XML. The returned format can be forced to JSON using a filter that adds the header you need and lets MVC resolve the JSON.

public class AcceptHeaderJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        actionContext.Request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));    
    }
}

So you can decorate the method you want to force a JSON response with this attribute and keep the same global JSON configuration and serialization as any other method.

Lauren Rutledge
  • 1,195
  • 5
  • 18
  • 27
animalito maquina
  • 2,264
  • 3
  • 20
  • 35
4

Try this ApiController.Ok.

You just do return Ok(model) and change the return type to IHttpActionResult.

Example:

public class CarController : ApiController
{
    [System.Web.Mvc.Route("api/Player/videos")]
    public IHttpActionResult GetVideoMappings()
    {
        var model = new MyCarModel();
        return Ok(model);
    }
}
Lauren Rutledge
  • 1,195
  • 5
  • 18
  • 27
Mohammad Ali
  • 551
  • 7
  • 17
  • This is .Net core and he is asking about ApiController within .Net Framework – Sigex Nov 25 '19 at 15:27
  • @Sigex no it is not https://learn.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api – Mohammad Ali Apr 20 '21 at 08:03
2

For API controllers it is up to the caller to determine how the response is created. Unless you specifically add code to force only one type of response. Here is a simple example of an API method and what happens when called requesting XML, or JSON.

public class XmlEampleController : ApiController
{
    [HttpPost]
    [ActionName("MyOrderAction")]
    public HttpResponseMessage MyOrder([FromBody]MyOder order)
    {
        if (order != null)
        {
            return Request.CreateResponse<MyOder>(HttpStatusCode.Created, order);
        }
        return Request.CreateResponse(HttpStatusCode.BadRequest);
    }

[Serializable]
public partial class MyOder
{
    private string dataField;
    public string MyData
    {
        get
        {
            return this.dataField;
        }
        set
        {
            this.dataField = value;
        }
    }
}

}

Sample:Help page display

Brian from state farm
  • 2,825
  • 12
  • 17
0

Maybe the issue is with WebApiConfig file. At the end of the file add these 2 lines

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

It is in Project/App_Start/WebApiConfig.cs For asp.net MVC

zetawars
  • 1,023
  • 1
  • 12
  • 27