Geeks With Blogs

News ASP.net Forms Justin Hoffman

Justin Hoffman

During the upgrade of a solution from the Web Api Preview 6 to MVC 4 Beta Web Api, I encountered a bug with a custom MediaTypeFormatter.  In the Api controller I had a need to take the posted content object as well as some string identifiers/keys as parameters.  The problem I encountered as that if I utilized a custom MediaTypeFormatter, these values came in as Null

Take the following Api controller Post:

       // POST /api/values
        public HttpResponseMessage<SomeObj> Post(string key, string id, SomeObject value)

The string key always came in null.  However, if I switch and used one of the built in formatters XmlMediaTypeFormatter for example, this was not a problem.  It is my understanding that this issue will be fixed post Beta.  I posted my problem on MSDN and did receive a response, you can find it here.

In the meantime, something like the following can be used for a workaround.

Add an Action Filter to handle the parameter binding for you.  Below is an example of such a filter.  It currently would only work with string or int route parameterrs (but can be changed/expanded).

    public class ParameterFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
          if (actionContext.Request.Method != HttpMethod.Get)
            {
                var idParams = actionContext.ControllerContext.Request.GetRouteData();
                foreach (var item in idParams.Values)
                {
                    object value;
                    var result = actionContext.ActionArguments.TryGetValue(item.Key, out value);
                    if (result)
                    {
                        var parm = actionContext.ActionDescriptor.GetParameters().Where(x => x.ParameterName == item.Key).SingleOrDefault();
                        var type = parm.ParameterType;
                        // Check Action parameter type and convert if needed
                        if (type == typeof(int))
                        {
                             actionContext.ActionArguments[item.Key] = Convert.ToInt32(item.Value);
                        }

                        if (type == typeof(string))
                        {
                             actionContext.ActionArguments[item.Key] = item.Value.ToString();
                        }
                    }
                }
            }

            base.OnActionExecuting(actionContext);
            }
    }

Register the Action Filter in the Global.asax

        protected void Application_Start()
        {
            GlobalConfiguration.Configuration.Formatters.Clear();
           
            GlobalConfiguration.Configuration.Filters.Add(new ParameterFilter());
            AreaRegistration.RegisterAllAreas();
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
            BundleTable.Bundles.RegisterTemplateBundles();
        }
Posted on Tuesday, March 6, 2012 9:08 AM | Back to top


Comments on this post: MVC 4 Beta Web Api: Bug with Binding Route Values when using a custom MediaTypeFormatter

# re: MVC 4 Beta Web Api: Bug with Binding Route Values when using a custom MediaTypeFormatter
Requesting Gravatar...
Just what I was looking for, thanks!
Left by Jeff Doolittle on Mar 09, 2012 1:18 AM

# re: MVC 4 Beta Web Api: Bug with Binding Route Values when using a custom MediaTypeFormatter
Requesting Gravatar...
Excellent - just what I needed.
Left by LittleColin on May 15, 2012 6:55 AM

# re: MVC 4 Beta Web Api: Bug with Binding Route Values when using a custom MediaTypeFormatter
Requesting Gravatar...
no suitable method found to override? What am I doing wrong?
Left by george on May 21, 2012 7:28 PM

# re: MVC 4 Beta Web Api: Bug with Binding Route Values when using a custom MediaTypeFormatter
Requesting Gravatar...
@george This is runtime error or you can't get it to compile?
Left by Justin on May 22, 2012 8:36 AM

# re: MVC 4 Beta Web Api: Bug with Binding Route Values when using a custom MediaTypeFormatter
Requesting Gravatar...
actionContext.ControllerContext.Request.GetRouteData();

GetRouteData() not found.
What else we can use?
Left by Chintan on May 23, 2012 11:45 PM

# re: MVC 4 Beta Web Api: Bug with Binding Route Values when using a custom MediaTypeFormatter
Requesting Gravatar...
@Chintan, make sure you are have correct namespace
using System.Web.Http;
GetRouteData is an extension method in System.Web.Http
Left by Justin on May 24, 2012 7:21 AM

# re: MVC 4 Beta Web Api: Bug with Binding Route Values when using a custom MediaTypeFormatter
Requesting Gravatar...
Can you tell me if you replaced the custom MediaTypeFormatter with the Filter?
I am trying to do a similar action, but in my case, the route values are filled and is the third object that is null. When debugging the formatter the returned object is ok.
Left by Sandra on May 31, 2012 2:00 PM

# re: MVC 4 Beta Web Api: Bug with Binding Route Values when using a custom MediaTypeFormatter
Requesting Gravatar...
@Sandra.. I didn't replace the MediaTypeFormatter with the filter, I used them both in combindation. In your MediaTypeFormatter in the "CanReadType" method, are you exluding anything? I remember being able to produce your problem by just returning True in CanReadType. But if you exelcude IKeyValueModel it should work
Left by Justin on May 31, 2012 2:11 PM

# re: MVC 4 Beta Web Api: Bug with Binding Route Values when using a custom MediaTypeFormatter
Requesting Gravatar...
Thanks a lot! With that change in the CanReadType I now have the same problem you had :)
Now adding the filter...
Left by Sandra on May 31, 2012 2:25 PM

Your comment:
 (will show your gravatar)


Copyright © Justin Hoffman | Powered by: GeeksWithBlogs.net | Join free