我是一名WCF开发人员,是MVC的新成员。尝试将我的WCF API作为ApiControllers集成到MVC应用程序中(如果这是值得的努力仍然是一个很大的问题)。
我有来自jQuery插件的请求:
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"}
我的控制器看起来像这样:
public class PublicController : ApiController
{
[HttpPost]
public string DoAction(string myParam)
{
return "Test";
}
}
并且,路由片看起来像这样:
config.Routes.MapHttpRoute(
name: "PublicApi",
routeTemplate: "api/{controller}/{action}"
);
我收到此错误:
{
"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."
}
不接受任何JSON参数的方法工作正常,但接受JSON参数的方法不起作用。我必须能够将复杂的JSON传递给方法。在WCF中,WCF为我处理了从JSON到对象的转换。
你知道我为什么会收到这个错误吗?我能否像在WCF中那样在MVC中无缝地传递/接收复杂的JSON?
答案 0 :(得分:6)
如果您检查了发送{"myParam":"test"}
的JSON,那么您将看到Darin指出的内容,即您需要一个模型来包含您的属性,例如将{“myParam”:“test”}运行到以下工具中:http://json2csharp.com/并获得:
public class RootObject
{
public string myParam { get; set; }
}
默认情况下,您使用简单类型字符串的先前方法签名将被WebApi视为UrlParameter(与public string DoAction([FromUri]string myFoo)
相同)。您可以证明这是为了保留代码,因为此URL应该有效:
http://localhost:50381/Api/Public/DoAction?myParam=something
使用JSON.NET的正文序列化程序无法自行解析简单的.NET类型,因此您需要创建一个简单的模型来托管它。然后,这将使用from body binder public string DoAction([FromBody]RootObject myFoo)
答案 1 :(得分:2)
一如既往地定义视图模型:
public class MyModel
{
public string MyParam { get; set; }
}
然后让您的控制器操作将此视图模型作为参数:
public class PublicController : ApiController
{
[HttpPost]
public string DoAction(MyModel model)
{
return "Test_" + model.MyParam;
}
}
最后调用控制器操作:
<script type="text/javascript">
$.ajax({
url: '@Url.HttpRouteUrl("PublicApi", new { controller = "public", action = "doaction" })',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ "myParam": "test" }),
sucecss: function (result) {
console.log(result);
}
});
</script>
备注:您通过在路由中包含操作名称来违反RESTful约定。在RESTful路由中,您使用的是资源,而不是使用操作。因此,您的控制器代表您正在操作的资源,HTTP谓词代表您正在调用的操作。因此,您将使用Get,Post,Patch和Delete等动作名称,并根据客户端使用的HTTP动词,路由引擎将自动调度到相应的动作。