I am a WCF dev, new to MVC. Trying to integrate my WCF API as ApiControllers into an MVC application (still big question if it's a worthy effort).
I have this request from a jQuery plugin:
POST http://localhost:18698/Api/Public/DoAction HTTP/1.1
....
Content-Type: application/json; charset=UTF-8 Accept:
application/json, text/javascript, */*; q=0.01
{"myParam":"test"}
My controller looks like this:
public class PublicController : ApiController
{
[HttpPost]
public string DoAction(string myParam)
{
return "Test";
}
}
And, the routing piece looks like this:
config.Routes.MapHttpRoute(
name: "PublicApi",
routeTemplate: "api/{controller}/{action}"
);
I am getting this error:
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:18698/Api/Public/DoAction'.",
"MessageDetail": "No action was found on the controller 'Public' that matches the request."
}
Methods that don't accept any JSON parameters work fine, but the ones that accept JSON parameters don't work. I have to be able to pass complex JSON to the methods. In WCF, translation from JSON to objects was handled for me by WCF.
Do you know why I am getting this error? Would I be able to pass/receive complex JSON as seamlessly in MVC as I did in WCF?
As always start by defining a view model:
then have your controller action take this view model as parameter:
finally invoke the controller action:
Remark: You are violating the RESTful conventions by including the action name in your routes. In RESTful routes you are working with resources, not with actions. So your controller represents the resource you are manipulating and the HTTP verbs represent the actions you are calling. So you would use action names such as Get, Post, Patch and Delete and based on the HTTP verb used by the client, the routing engine will automatically dispatch to the corresponding action.
If you examine the JSON you were sending
{"myParam":"test"}
then you will see what Darin points out i.e. you need a Model to contain your property e.g. run {"myParam":"test"} into the following tool: http://json2csharp.com/ and you get:Your previous method signature with the simple type of string would have been treated by WebApi as a UrlParameter by default (the same as
public string DoAction([FromUri]string myFoo)
). You can prove this as leaving you code as is this url should work:The body serialiser using JSON.NET won't be able to parse a simple .NET type on it's own and therefore you need to create a simple Model to host it on. This will then use the from body binder
public string DoAction([FromBody]RootObject myFoo)