I have a method that is receiving more than one parameter. The method signature with attributes look like the following:
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
public int AddUser(string firstName, string lastName, string emailaddress) { // actions here }
However, when I use this method, I get the following exception:
The HttpOperationHandlerFactory is unable to determine the input
parameter that should be associated with the request message content
for service operation ‘Initiate’. If the operation does not expect
content in the request message use the HTTP GET method with the
operation. Otherwise, ensure that one input parameter either has it’s
IsContentParameter property set to ‘True’ or is a type that is
assignable to one of the following: HttpContent, ObjectContent`1,
So, I’ve created a custom object (such as below) to be passed in.
[DataContract]
public class UserToAdd {
[DataMember] public string firstName { get; set; }
[DataMember] public string lastName { get; set; }
[DataMember] public string emailAddress { get; set; }
}
Using this new signature:
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
public int AddUser(UserToAdd user) { // actions here }
When I do that, I get a 404. It seems I can’t win. Any suggestions?
If you want to create routes declaratively you can. I had to do this as I had inherited a bunch of non-restful URIs that had to be supported for backwards compatibility reasons. I created my own attribute to describe URIs, constraints and HTTP methods. This is effectively a replacement for WebInvoke/WebGet. I reflect over my service methods on start-up to discover routes and call MapHttpRoute() as appropriate. Each of my routes specifies the controller and action explicitly. This approach is good for RPC style APIs, but it required quite a lot of heavy lifting. The nice part is that it keeps the definition of routes with the methods – this is not something web api gives you explicitly.
So whilst RPC style is possible, it’s not idiomatic. Web API is strongly biased out of the box towards RESTful APIs with convention driven mapping of routes to services and methods – in this way very generic routes are registered and conventions do the rest. That largely avoids the issues of defining routes away from their corresponding actions. If you can I would convert to the RESTful/convention approach of Web API, as you are otherwise fighting the framework a little.