Binding to route value and CustomMediaTypeFormatterhttp://forums.asp.net/t/1770919.aspx/1?Binding+to+route+value+and+CustomMediaTypeFormatterThu, 01 Mar 2012 00:13:45 -050017709194838280http://forums.asp.net/p/1770919/4838280.aspx/1?Binding+to+route+value+and+CustomMediaTypeFormatterBinding to route value and CustomMediaTypeFormatter <p>This works:</p> <pre class="prettyprint">public Task&lt;HttpResponseMessage&gt; UpdateOrder() { int orderId = Convert.ToInt32(this.Request.GetRouteData().Values[&quot;orderId&quot;]);</pre> <p>But this:</p> <pre class="prettyprint"> public Task&lt;HttpResponseMessage&gt; UpdateOrder(int orderId) { //int orderId = Convert.ToInt32(this.Request.GetRouteData().Values["orderId"]);</pre> <p>Causes this exception to be returned</p> <pre class="prettyprint">"{\"ExceptionType\":\"System.InvalidOperationException\",\"Message\":\"No 'MediaTypeFormatter' is available to read an object of type 'Int32' with the media type 'application\\/vnd.weborder+xml'.\",\"StackTrace\":\" at System.Net.Http.ObjectContent.SelectAndValidateReadFormatter(Boolean acceptNullFormatter)\\u000d\\u000a at System.Net.Http.ObjectContent.ReadAsyncInternal[T](Boolean allowDefaultIfNoFormatter)\\u000d\\u000a at System.Web.Http.ModelBinding.RequestContentReader.ReadWholeBodyAsync(HttpActionContext actionContext, Type modelType)\\u000d\\u000a at System.Web.Http.ModelBinding.RequestContentReader.ReadContentAsync(HttpActionContext actionContext)\\u000d\\u000a at System.Web.Http.ModelBinding.DefaultActionValueBinder.BindValuesAsync(HttpActionContext actionContext, CancellationToken cancellationToken)\\u000d\\u000a at System.Web.Http.ApiController.&lt;&gt;c__DisplayClass3.&lt;ExecuteAsync&gt;b__0()\\u000d\\u000a at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerCon text, CancellationToken cancellationToken)\\u000d\\u000a at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken)\\u000d\\u000a at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)\"}"</pre> 2012-02-17T22:03:40-05:004838283http://forums.asp.net/p/1770919/4838283.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>I am not sure about the route value binding part, but regarding the mediatypeformatter, you have added it as part of the Formatters list on the Configuration object...right?</p> 2012-02-17T22:17:05-05:004838298http://forums.asp.net/p/1770919/4838298.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>I doubt this is the case, but I know that for some properties, once they are model bound, they are removed from the contextual elements. However, wrt RouteData, I would think this a bug.</p> 2012-02-17T23:15:19-05:004838299http://forums.asp.net/p/1770919/4838299.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>What does your route table look like? Is the route data for the orderId parameter present?</p> 2012-02-17T23:19:33-05:004838640http://forums.asp.net/p/1770919/4838640.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>Chris did you add your custom vnd.mediatype names to the supported collection on the Json formatter?&nbsp; At least in preview 6 this error happens because the framework can't find a formatter to deserialize your media type.&nbsp; I solved that by adding all the media type in my system to the formatter, in my case using reflection (I store the media type on the actions).</p> 2012-02-18T09:30:43-05:004841287http://forums.asp.net/p/1770919/4841287.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>Yes</p> 2012-02-20T13:29:11-05:004841290http://forums.asp.net/p/1770919/4841290.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>I believe so because I am able to manually pull the value out of the GetRouteData.Values dictionary.</p> <p></p> <p>This is how I map the route</p> <pre class="prettyprint">_config.Routes.MapHttpRoute(&quot;UpdateOrderApiUrl&quot;, &quot;api/orders/{orderId}&quot;, new { controller = &quot;OrdersApi&quot;, action = &quot;UpdateOrder&quot; }, new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) });</pre> 2012-02-20T13:30:57-05:004841291http://forums.asp.net/p/1770919/4841291.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>I didn't add my media types to the JsonFormatter.</p> <p>This all worked in preview6 though.</p> 2012-02-20T13:31:47-05:004841294http://forums.asp.net/p/1770919/4841294.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>It *feels* like it is trying to use my media type formatter to handle the conversion of the route parameters...but that is just guessing</p> 2012-02-20T13:32:46-05:004841298http://forums.asp.net/p/1770919/4841298.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>Try adding your media types to the formatter's SupportedMediaTypes and see if that works :)</p> <p></p> 2012-02-20T13:33:49-05:004841302http://forums.asp.net/p/1770919/4841302.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>That would be a bug though right?</p> 2012-02-20T13:37:57-05:004841306http://forums.asp.net/p/1770919/4841306.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>Don't think so.&nbsp; At least in preview 6 the formatters were picked based on what media types they supported.&nbsp; So when deserializing it looks at the Content-Type of the incoming request and picks a formatter based on that.<br> In my services I support both XML and JSON and add the media types as &#43;json and &#43;xml respectively.&nbsp; For example</p> <pre class="prettyprint">jsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue(&quot;application/vnd.weborder&#43;json&quot;)); xmlFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue(&quot;application/vnd.weborder&#43;xml&quot;));</pre> 2012-02-20T13:41:30-05:004841311http://forums.asp.net/p/1770919/4841311.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>But it should never be involving those formatters should it? I have my own formatter that handles this media type. I wouldn't expect the formatters to be involved in pulling data out of the url.</p> 2012-02-20T13:44:16-05:004841319http://forums.asp.net/p/1770919/4841319.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>Ok I didn't know you had your own custom formatter, but in that case you should be adding your media types to the .SupportedMediaTypes collection on it and registering it in the global config.</p> <p>Btw. your error states it cannot map your media type to int.&nbsp; Are you doing a post with the Content-Type header set to that media type? Also, if you are posting a body, why isnt it declared as a method param?</p> <p>It just sounds like the framework has a body with a custom media type, and its trying to map that to parameters on your method.</p> 2012-02-20T13:49:10-05:004841328http://forums.asp.net/p/1770919/4841328.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>Yes, media types all registered.</p> <p>content type header is set to my custom media type which is the body of the post.</p> <p>In my method body I read the request as a stream and then populate my custom object. I do this because I want some other things to happen before i parse the message.</p> <p></p> 2012-02-20T13:56:16-05:004841333http://forums.asp.net/p/1770919/4841333.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>What other things? Cant you do that in a DelegatingHandler or action filter and then put the body as a parameter on the action.</p> 2012-02-20T13:58:36-05:004841360http://forums.asp.net/p/1770919/4841360.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>They could have technically been done in a Delegating handler, but were different for each method..so rather than have this 1:1 with a delegating handler and a method I just put it in the method. Yes, I could probably use attributes and reflection and manage to get it all into a single handler but this was just nice and simple.</p> 2012-02-20T14:15:00-05:004841363http://forums.asp.net/p/1770919/4841363.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>Sounds like a perfect job for an action filter (similar to the Operation Handlers that were in preview bits), those are method specific.</p> 2012-02-20T14:16:25-05:004846077http://forums.asp.net/p/1770919/4846077.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p></p> <blockquote><span class="icon-blockquote"></span> <h4>chrisortman</h4> <p></p> <p>But it should never be involving those formatters should it? I have my own formatter that handles this media type. I wouldn't expect the formatters to be involved in pulling data out of the url.</p> <p></p> </blockquote> <p></p> <p>Right, we'll address this issue where model binder is trying to read&nbsp;the body unnecessarily.&nbsp;Meanwhile, can you try workaround it by adding the [FromUri] attribute?</p> <pre class="prettyprint">public Task&lt;HttpResponseMessage&gt; UpdateOrder([FromUri] int orderId)</pre> 2012-02-23T01:53:30-05:004846617http://forums.asp.net/p/1770919/4846617.aspx/1?Re+Binding+to+route+value+and+CustomMediaTypeFormatterRe: Binding to route value and CustomMediaTypeFormatter <p>you can attribute the parameter &quot;orderId&quot; with [FromUri] to make it work.</p> 2012-02-23T07:39:51-05:00