支持WebApi中的GET *和* POST

时间:2013-08-05 04:40:54

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

我们有一个测试模型。

public class TestRequestModel
{
    public string Text { get; set; }
    public int Number { get; set; }
}

我希望此服务能够接受以下请求:

  • GET / test?Number = 1234& Text = MyText
  • 带标题的
  • 发布/测试内容类型:application / x-www-form-urlencoded 和正文:数字= 1234&amp; Text = MyText < /强>
  • 发布/测试,标题为:内容类型:application / json 和正文: {“Text”:“已提供!”,“数字”: 9876}

路由按以下方式配置:

_config.Routes.MapHttpRoute(
   "DefaultPost", "/{controller}/{action}",
   new { action = "Post" }, 
   new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) });

_config.Routes.MapHttpRoute(
   "The rest", "/{controller}/{action}",
   defaults: new { action = "Get" });

我的控制器看起来像这样:

public class TestController : ApiController
{
    [HttpGet]
    public TestResponseModel Get([FromUri] TestRequestModel model)
    {
       return Do(model);
    }

    [HttpPost]
    public TestResponseModel Post([FromBody] TestRequestModel model)
    {
       return Do(model);
    }
    (...)

这似乎是一个可接受的锅炉板代码量,但我仍然希望尽可能避免它。

拥有额外路线也不理想。我害怕MVC / WebAPi路线,我相信它们是邪恶的。

有没有办法避免使用两种方法和/或 DefaultPost 路由?

1 个答案:

答案 0 :(得分:8)

您要求的内容在ASP.NET Web API中并不常见。在ASP.NET MVC中,通常使用相同的操作方法来处理初始GET和后续回发(POST)。 ASP.NET Web API用于构建HTTP服务,GET用于检索资源而不更改系统中的任何内容,而POST则用于创建新资源,如Matthew所指出的那样。

无论如何,在Web API中使用一个动作方法来实现这一点并非不可能。但是您希望相同的操作方法不仅可以处理GET和POST,还可以进行模型绑定和格式化程序绑定。模型绑定(类似于MVC)将请求URI,查询字符串等绑定到参数,而格式化程序绑定(Web API唯一)将主体内容绑定到参数。默认情况下,简单类型从URI,查询字符串和body中的复杂类型绑定。因此,如果您有一个参数为string text, int number, TestRequestModel model的操作方法,则可以从URI或正文进行Web API绑定,在这种情况下,您需要检查哪些不是空的并使用它。但是,不幸的是,这样的解决方案看起来更像是黑客攻击。或者,如果您希望从URI /查询字符串和正文填充相同的复杂类型,则需要编写自己的参数绑定器来检查请求部分并相应地填充参数。

此外,您不需要两个路由映射。像这样的默认值就可以了。

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);