HttpResponseMessage that plays nice with content negotiationhttp://forums.asp.net/t/1786499.aspx/1?HttpResponseMessage+that+plays+nice+with+content+negotiationSat, 21 Apr 2012 21:06:24 -040017864994904715http://forums.asp.net/p/1786499/4904715.aspx/1?HttpResponseMessage+that+plays+nice+with+content+negotiationHttpResponseMessage that plays nice with content negotiation <p>I have an API method from which I want to return either XML, HTML, plain text, or JSON. The data in question is not an object per-se so I can't just return an object to the framework and have it serialize for me. So I am returning a HttpResponseMessage from the method with StringContent to specify the actual content to return.</p> <p>My question is, how can I determine from within the API method which content type the client has requested? I'd like to avoid passing this as a custom parameter to the method because the other methods will use the built-in content type negotiation which uses the Accept or Content-Type request headers. While I could just access the request headers directly, this seems wrong since content type negotiation can be influenced by other factors as well (such as media type mappings.)</p> <p>Sorry if the question sounds unclear. I am very new to ASP.NET MVC and the Web API in particular.</p> 2012-03-28T18:26:33-04:004904721http://forums.asp.net/p/1786499/4904721.aspx/1?Re+HttpResponseMessage+that+plays+nice+with+content+negotiationRe: HttpResponseMessage that plays nice with content negotiation <p>Your best bet is to take serialization into your own hands. You can see a sample at <a href="https://github.com/WebApiContrib/WebAPIContrib/tree/master/samples/WebApi.Conneg.Web"> WebApiContrib</a>.</p> 2012-03-28T18:29:11-04:004904887http://forums.asp.net/p/1786499/4904887.aspx/1?Re+HttpResponseMessage+that+plays+nice+with+content+negotiationRe: HttpResponseMessage that plays nice with content negotiation <p>There is a property called 'Request' which is available for every ApiController derived controller. This property will give you access to the current request from which you should be able to get the information about the headers you want. I am not sure if i answered your question.</p> 2012-03-28T20:33:09-04:004905255http://forums.asp.net/p/1786499/4905255.aspx/1?Re+HttpResponseMessage+that+plays+nice+with+content+negotiationRe: HttpResponseMessage that plays nice with content negotiation <p>@kiran: That's what I was trying to avoid doing. I wanted to use the built-in content type negotiation and just get access to the decision. If I use the request headers directly, I'll be duplicating the effort and it wouldn't adapt with changes to the conneg strategy.</p> 2012-03-29T05:12:37-04:004905258http://forums.asp.net/p/1786499/4905258.aspx/1?Re+HttpResponseMessage+that+plays+nice+with+content+negotiationRe: HttpResponseMessage that plays nice with content negotiation <p>@panesofglass: I'm already doing the serialization myself, but your sample (in addition to the library's source) has pointed me in the right direction. It doesn't look like it's going to be as straightforward as I thought since content negotiation apparently isn't performed at all until a serializable object is returned. Since I'm handling the serialization, looks like I have to do the content type negotiation as well.</p> 2012-03-29T05:15:14-04:004910091http://forums.asp.net/p/1786499/4910091.aspx/1?Re+HttpResponseMessage+that+plays+nice+with+content+negotiationRe: HttpResponseMessage that plays nice with content negotiation <p></p> <blockquote><span class="icon-blockquote"></span> <h4>josheinstein</h4> I wanted to use the built-in content type negotiation and just get access to the decision</blockquote> <p></p> <p>May be you are looking this,</p> <pre class="prettyprint">public class MyFormatterSelector : FormatterSelector { protected override MediaTypeFormatter OnSelectWriteFormatter(Type type, FormatterContext formatterContext, IEnumerable&lt;MediaTypeFormatter&gt; formatters, out MediaTypeHeaderValue mediaType) { var m = base.OnSelectWriteFormatter(type, formatterContext, formatters, out mediaType); return m; } protected override MediaTypeFormatter OnSelectReadFormatter(Type type, FormatterContext formatterContext, IEnumerable&lt;MediaTypeFormatter&gt; formatters) { var m = base.OnSelectReadFormatter(type, formatterContext, formatters); return m; } } GlobalConfiguration.Configuration.ServiceResolver.SetService(typeof(IFormatterSelector), new MyFormatterSelector());</pre> <p><br> <br> </p> <p></p> 2012-04-01T05:35:37-04:004943597http://forums.asp.net/p/1786499/4943597.aspx/1?Re+HttpResponseMessage+that+plays+nice+with+content+negotiationRe: HttpResponseMessage that plays nice with content negotiation <p>FWIW, FormatterSelector has been changed and renamed to IContentNegotiator. But you can still get it and explicitly invoke this method:</p> <p>&nbsp;&nbsp; ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable&lt;MediaTypeFormatter&gt; formatters);</p> <p>&nbsp;</p> 2012-04-20T22:05:30-04:004943885http://forums.asp.net/p/1786499/4943885.aspx/1?Re+HttpResponseMessage+that+plays+nice+with+content+negotiationRe: HttpResponseMessage that plays nice with content negotiation <p></p> <blockquote><span class="icon-blockquote"></span> <h4>Mike Stall</h4> FWIW, FormatterSelector has been changed and renamed to IContentNegotiator. But you can still get it and explicitly invoke this method:</blockquote> <p></p> <p>Thanks But I think Current Official Build(not talking about current source) does not have IContentNegotiator. BTW, Thanks for letting us.</p> <p></p> 2012-04-21T07:59:27-04:004944332http://forums.asp.net/p/1786499/4944332.aspx/1?Re+HttpResponseMessage+that+plays+nice+with+content+negotiationRe: HttpResponseMessage that plays nice with content negotiation <p>Josh,</p> <p>Is this just for a single request or for all of your requests in the API?&nbsp;</p> <p>If it's just for a single request it's probably easiest to just case block your output based on the specified option. You can then use the appropriate Request headers to examine the requested accept headers and decide what to do. Alternately (in post beta builds) you can use Request.CreateResponse() to create the Response object with the conneg matched output message type.</p> <p>I think the latter is probably not going to work well if you are returning non-fixed formats like HTML strings etc., but you can create the response and check if it's XML/JSON and then use that or create a new Response object for the non-internally supported output types like html.&nbsp;If all your requests require this you should probably create a custom output Formatter that handles all the output types you're creating in one place.&nbsp;You then can check the accept headers in there and create the appropriate response. Frankly though if all your requests do this then you're not taking great advantage of what the API offers (other than routing) really and you might be better off just creating a custom Http Handler, which might just be more straight forward.</p> <p>&#43;&#43;&#43; Rick ---</p> <p></p> 2012-04-21T21:06:24-04:00