Buda Gavril
Buda Gavril

Reputation: 21657

web api: add data to the HttpResponseMessage

I have an action in my web api that is returning a HttpResponseMessage:

public async Task<HttpResponseMessage> Create([FromBody] AType payload)
{
    if (payload == null)
    {
        throw new ArgumentNullException(nameof(payload));
    }

    await Task.Delay(1);

    var t = new T { Id = 0, Name = payload.tName, Guid = Guid.NewGuid() };

    var response = new MyResponse { T = t };

    var result = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ObjectContent(typeof(MyResponse), response, new JsonMediaTypeFormatter { SerializerSettings = { NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore } }) };

    return result;
}

Now, my problem is that if a request is made and the request's Content-Type is application/xml, I should put the response's body using a xml formatter.

Is there a way to use a generic class and let the framework decide what formatter to use at runtime based on the request's content type?

Upvotes: 3

Views: 5476

Answers (2)

Dan Harms
Dan Harms

Reputation: 4840

An easier way to do this is to use the handy methods in Web API 2 ApiController.

[HttpPost]
public async Task<IHttpActionResult> Create([FromBody] AType payload)
{
    if (payload == null) 
    {
        return BadRequest("Must provide payload");
    }

    await Task.Delay(1);

    var t = new T { Id = 0, Name = payload.tName, Guid = Guid.NewGuid() };

    var response = new MyResponse { T = t };

    return Ok(response);
}

Upvotes: 0

Nkosi
Nkosi

Reputation: 247471

Use the CreateResponse extension method on the request and it will allow for content negotiation based on associated request. If you want to force the content type based on the content type of the request take it from the request and include it in the create response overloads.

public class MyApitController : ApiController {
    [HttpPost]
    public async Task<HttpResponseMessage> Create([FromBody] AType payload) {
        if (payload == null) {
            throw new ArgumentNullException(nameof(payload));
        }

        await Task.Delay(1);

        var t = new T { Id = 0, Name = payload.tName, Guid = Guid.NewGuid() };

        var response = new MyResponse { T = t };

        var contentType = Request.Content.Headers.ContentType;

        var result = Request.CreateResponse(HttpStatusCode.OK, response, contentType);

        return result;
    }

}

The type returned should ideally be based on what the request indicates it wants to accept. The framework does allow flexibility on that topic.

Check this for more info Content Negotiation in ASP.NET Web API

Upvotes: 1

Related Questions