一个简单的帖子请求不会路由到web api控件

时间:2018-02-06 13:43:50

标签: asp.net-web-api

这是WebApiConfig.cs中路由的配置

// Web API configuration and services
config.Routes.MapHttpRoute(
  name: "ActionApi",
  routeTemplate: "api/{controller}/{action}");
// Web API routes



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

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

config.Routes.MapHttpRoute(
  name: "MSApi",
  routeTemplate: "api/{controller}/ms/{action}",
  defaults: new { controller="GPI" }
);
config.MapHttpAttributeRoutes();

这是我的控制器。

  [HttpPost]
    public IHttpActionResult payout(string t)
    {

这是httpRequest

POST /api/Race/payout HTTP/1.1
Host: localhost
User-Agent: PostmanRuntime/7.1.1
Content-Length: 4
Accept: */*
Accept-Encoding: gzip, deflate
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
Postman-Token: f2adaf2e-d518-4924-bd28-8a901bd1846f
X-Forwarded-For: 84.228.5.88
X-Forwarded-Proto: https
X-Original-Host: integerator.eu.ngrok.io

t=da

我在这个控制器中有一些功能。控制器的名称没有问题。行动被召唤。

更多细节。如果我使用[FromBody]属性,我得到t值为null。

[HttpPost]
    public IHttpActionResult payout([FromBody]string t)
    {

t变量为空。

我必须将t作为字符串变量。我不想把它改成另一种类型。

请帮助我理解尴尬的路由行为。

更新

我有以下两个动作:

 [HttpPost]
    public IHttpActionResult payout(string t)
    {

   public IHttpActionResult payout([FromBody] Object req)
        {

我提到的http请求总是会转到第二个付款操作,而不是第一个操作。 我希望第一个动作使用string参数拦截该post请求。 我不明白为什么第一个动作不处理请求。即使第二个动作被完全删除也是如此。

我尝试使用名为' Post man'。

的工具发布不同的http内容类型标题。

这是我在控制器中第一次操作时得到的错误,

{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:55392/api/Race/payout'.",
"MessageDetail": "No action was found on the controller 'Race' that 

matches the request."
}

我考虑过覆盖与对象的模型绑定,这里描述的方式如下:

https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

但我不认为任何相关的东西。有没有办法破解路由的工作方式并拦截传入的请求?

1 个答案:

答案 0 :(得分:0)

首先,在这种情况下,您必须使用FromBody属性,因为string是默认情况下从Url反序列化的简单类型。查看文章Parameter Binding in ASP.NET Web API了解详细信息。否则,只要您没有可以匹配缺少t参数的路由,就会出现404错误。

如您在问题中所述,如果使用t,您将在FromBody变量中获得空值。当您发送form-urlencoded数据时,ASP.NET Web Api使用FormUrlEncodedMediaTypeFormatter来反序列化请求数据。此格式化程序通过将请求中的键值映射到保持对象的属性或字段来完成其工作。因此,如果您声明以下类:

public class SomeClass
{
    public string T { get; set; }
}

并将您的操作更改为

[HttpPost]
public IHttpActionResult payout([FromBody] SomeClass obj)
{
    // ...
}

并发送相同的请求,您将获得obj个实例,T属性填充"da"值。

使用默认的form-urlencoded媒体类型格式化程序,您无法发送相同的请求并将数据直接反序列化为字符串变量。

以下是保持动作与字符串变量从主体反序列化的选项:

  1. 将请求内容类型更改为application/json并在请求正文中发送以下数据(需要围绕该值的引号):

    “DA”

    JsonMediaTypeFormatter将正确反序列化此类字符串值。

  2. 如果要保留内容类型,则应为form-urlencoded数据实现自定义媒体类型格式化程序,该数据将直接反序列化为字符串。有很多例子如何实现自定义格式化程序。以下是其中一些:

    Simple Custom Media Formatter in ASP.Net Web API

    Creating Custom CSVMediaTypeFormatter In ASP.NET Web API for Comma-Separated Values (CSV) Format

  3. 希望这会有所帮助。