我正试图弄清楚Web API路由背后的疯狂。
当我尝试发布这样的数据时:
curl -v -d "test" http://localhost:8088/services/SendData
我收到404,并出现以下错误消息:
{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:8088/services/SendData'.","MessageDetail":"No action was found on the controller 'Test' that matches the request."}
以下是我的测试服务器的代码。
public class TestController : ApiController
{
[HttpPost]
public void SendData(string data)
{
Console.WriteLine(data);
}
}
class Program
{
static void Main(string[] args)
{
var config = new HttpSelfHostConfiguration("http://localhost:8088");
config.Routes.MapHttpRoute(
name: "API Default",
routeTemplate:"services/SendData",
defaults: new { controller = "Test", action = "SendData"},
constraints: null);
using (var server = new HttpSelfHostServer(config))
{
server.OpenAsync().Wait();
Console.WriteLine("Press Enter to quit.");
Console.ReadLine();
}
}
}
更一般地说,为什么ASP.NET团队决定使MapHttpRoute方法如此混乱。为什么需要两个匿名对象....如何知道这些对象实际需要哪些属性?
MSDN没有提供任何帮助:http://msdn.microsoft.com/en-us/library/hh835483(v=vs.108).aspx
如果你问我,动态类型语言的所有痛苦都没有任何好处......
答案 0 :(得分:8)
同意你,这是一个疯狂的地狱,你需要指定data
参数应该从POST有效负载绑定,因为Web API自动假定它应该是查询字符串的一部分(因为它是一个简单的类型):
public void SendData([FromBody] string data)
为了让疯狂更加糟糕,你需要在=
之前添加POST有效负载(是的,这不是拼写错误,它是等号):
curl -v -d "=test" http://localhost:8088/services/SendData
你可以在this article
中阅读更多关于疯狂的内容。
或者停止疯狂并尝试ServiceStack
。
答案 1 :(得分:2)
使用此签名,每次都可以使用。
public class TestController : ApiController
{
[HttpPost]
[ActionName("SendData")]
public HttpResponseMessage SendData(HttpRequestMessage request)
{
var data = request.Content.ReadAsStringAsync().Result;
Console.WriteLine(data);
}
}
答案 2 :(得分:0)
尝试进行以下更改
public class TestController : ApiController
{
[HttpPost]
[ActionName("SendData")]
public void SendData(string data)
{
Console.WriteLine(data);
}
}
ActionName属性可能会解决此问题。否则,您还可以使用名称约定“Post”
public void Post(string data)
{
Console.WriteLine(data);
}
将Http Post直接发送到没有SendData的“服务”。