Search code examples
c#asp.net-web-api2content-negotiationmediatypeformatter

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?


Solution

  • 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