Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I have multiple POST methods in Web API with different complex parameter types?

I'm new to Web API... Here's my basic route:

config.Routes.MapHttpRoute(
  name: "Workitems",
  routeTemplate: "api/{controller}/{workitemID}",
  defaults: new { controller = "workitems", workitemID = RouteParameter.Optional }
);

Here's what I'd like to have:

public HttpResponseMessage Post( [FromBody] FolderModel theModel )
public HttpResponseMessage Post( [FromBody] DocumentModel theModel )

But, Web API doesn't find my second Post method. I've done lots of searching here and in Google but haven't found anything that works for me (well). I know I could add a 2nd unused parameter to the 2nd method - but that's too much of a hack. If this were normal C# code, the compiler would have no problem knowing which to choose b/c the methods have different signatures. But Web API is not smart enough.

I looked at custom constraints but that didn't seem appropriate. I also cannot use different {actions} as that violates RESTful constraints (no RPC, just resources) for my API. I also cannot put the 2nd Post on a different controller.

The only way I've gotten this to work is to wrap both FolderModel and DocumentModel in a parent object like this:

public class WorkitemCreateModel
{
    public DocumentModel Document { get; set; }
    public FolderModel Folder { get; set; }
}

public HttpResponseMessage Post( [FromBody] WorkitemCreateModel theModel )

Then have a single Post method that takes WorkitemCreateModel. But then it's the responsibility of the developer using my API that they must pass in WorkitemCreateModel but they must only pass in a DocumentModel object OR a FolderModel object. It's annoying too b/c my GET API can return either a DocumentModel object or a FolderModel object. So, it would be nice to just pass the object you get from the GET into the POST. But that doesn't work and they must wrap it in a WorkitemCreateModel object first.

Any other suggestions?

BTW: this website is the best! I've found SO many answers here!

like image 505
printf fan Avatar asked Apr 04 '15 02:04

printf fan


1 Answers

This might be an old post but I am adding this info just in case for people like me who came here looking for answers.

The short answer here is NO, its not possible.

The problem is with the way the routing works, especially the part about choosing what action method to use. Here is an extract from ASP .NET article (https://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection),

The goal of the selection algorithm is to select an action from the static description, before invoking any bindings. Therefore, complex types are excluded from the matching algorithm.

So while matching action methods to the path, Web API disregards all Complex types in the parameter list for that method and when you do that both of your methods have 0 parameters and that's why you are facing this problem.

Hope this helps...

like image 130
M22an Avatar answered Oct 13 '22 00:10

M22an