【问题标题】:Works for GET, not for POST (404 error)适用于 GET,不适用于 POST(404 错误)
【发布时间】:2013-04-28 23:23:32
【问题描述】:

我的 MVC4 项目中有一个 WebApi 控制器 ServicesApiController,其签名如下:

[Authorize(Roles = "sysadmin,Secretary")]
[AcceptVerbs("GET", "POST")]
public IEnumerable<Stock> TopRankedStocks(int maxRecords)
{
    // do stuff
    return result;
}

我的 api 控制器的路由如下所示:

config.Routes.MapHttpRoute(
    name: "ServicesApi",
    routeTemplate: "api/{controller}/{action}",
    defaults: new { controller = "ServicesApi", action="Index" }
    );

使用 IIS Express,如果我在浏览器中导航到 http://localhost:62281/api/ServicesApi/TopRankedStocks?maxRecords=20,我会得到一个不错的数据对象 xml 列表。

但是,如果我这样称呼它:

myHttpClient.BaseAddress = "http://localhost:62281/";
var arguments = new List<KeyValuePair<string, string>>(new[] { KeyValuePair<string, string>("maxRecords", "10") });
var content = new FormUrlEncodedContent(arguments);
var result = myHttpClient.PostAsJsonAsync("/api/ServicesApi/TopRankedStocks", content).Result;

...我收到 404(未找到)错误。

POST 操作在我的代码中的其他地方工作。我的应用程序和 IIS Express 的配置文件都允许所有动词。我不知道为什么这不起作用。有人能帮我介绍一下吗?

我不知道这是否是相关信息,但如果这里有一些价值,我会发布它:

  • Windows 8 64 w/4GB RAM
  • Visual Studio 2012 Professional Update 2 with Resharper
  • IIS Express 8
  • .NET Framework 4.5

【问题讨论】:

  • 尝试在 [AcceptVerbs("GET", "POST")] 之后添加System.Web.Http.HttpPost
  • @PSL 你能澄清一下吗?在哪里添加?
  • AcceptVerbs 后在public IEnumerable&lt;Stock&gt; TopRankedStocks 方法之上添加[System.Web.Http.HttpPost] 属性并试一试。
  • [FromBody]放在参数前面有影响吗?我知道这不适用于 GET,但可能有助于隔离问题。
  • [FromBody] 是一个参数属性,所以他说“在参数之前”。这里的主要问题是 POST 期望发送数据 - 但您在方法签名中的任何地方都不接受发送的数据。原始参数默认由 Uri 传递,但使用该属性您会说“我希望它从正文中获取”。我不确定这是否会破坏使用 GET 属性传递参数。你最好只创建两个不同的方法并使用 ActionName 属性。

标签: c# asp.net-mvc-4 asp.net-web-api http-status-code-404 iis-express


【解决方案1】:

我可以看到此控制器方法存在潜在问题:

问题是你的参数类型是int(原始类型)——只要你不将它标记为[FromBody],WebApi 参数绑定引擎就会假定它来自url。这就解释了为什么 GET 有效;当您不提供 url 中的值时,我不确定如何考虑 POST。

不过,如果您将 maxRecords 标记为 FromBody 并尝试通过 GET 方法使用它,它很可能会停止工作。 另外,请注意,如果您想将form-urlencoded 字符串用于仅具有一个键值对的帖子正文,那么要使其正常工作,您需要将其发布为"=10" 而不是"maxRecords=10"。

要检查这是否是导致方法失败的问题,我会暂时删除 GET 支持,只保留 POST,并将参数标记为 FromBody。

【讨论】:

  • 我没有意识到这一点。我重写了它以作为 GET 发送。谢谢。
  • @Jeremy - 只要您所做的只是获取信息(而不是创建资源),最好只允许 GET 以避免混淆 - 但是,如果 POST 方法旨在创建资源,我会将其分成不同的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-08
  • 2017-01-25
  • 2020-05-26
  • 1970-01-01
  • 2020-06-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多