如何使用Web Api将POSTHttpRoute POST到自定义操作?

时间:2013-03-26 14:18:17

标签: asp.net asp.net-web-api

我正试图弄清楚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

如果你问我,动态类型语言的所有痛苦都没有任何好处......

3 个答案:

答案 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的“服务”。