WebApi2请求的资源不支持发布

时间:2014-02-20 10:30:48

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

我已经阅读了大量描述相同错误消息的类似帖子,但它们似乎与我所遇到的不符。

我最近开始使用Web API并将我所有的MVC方法转换到我返回JSON等的位置,因此MVC将只渲染html,我将通过webapi控制器的ajax调用模型。

这是奇怪的事情,我可以从我的家庭apiController获取和POST(所以我可以登录/注册等),但我只能从我创建的区域中的API控制器获取。我得到了405(方法不允许),即使它的装饰和调用方式与其他控制器相同。我想路由是好的,否则它不会返回我的初始获取?

路由

 public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultAreaApi",
            routeTemplate: "api/{area}/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

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

控制器

 // Returns Model
 [HttpGet]
 public HttpResponseMessage SelectAgent()

 // The requested resource does not support http method 'POST'. 
 [HttpPost]
 public HttpResponseMessage SelectAgent(Guid id)

JQuery的

 // Works fine
    $.ajax({
            type: 'POST',
            url: '/api/Home/Login',
            headers: options.headers,
            contentType: "application/json; charset=utf-8",
            dataType: 'JSON',
            data: ko.toJSON(self.serverModel),
            success: function (response) {

   // Works fine
   $.getJSON("/api/Account/Users/SelectAgent", function (model) { ....

   // 405 
    $.ajax({
        type: 'POST',
        url: '/api/Account/Users/SelectAgent',
        headers: options.headers,
        contentType: "application/json; charset=utf-8",
        dataType: 'JSON',
        data: "{'id':'" + selectModel.agentId() + "'}",
        success: function (response) {....

传递的数据似乎很好(或者至少是它曾经使用过的MVC控制器)。

我根本没有修改过Home API Controller,我不明白我怎么能发布到那个而不是我的其他控制器。哎呀。

任何正确方向的指针都会很棒。

3 个答案:

答案 0 :(得分:12)

Web API仅查看基本数据类型的查询字符串参数。因此,当您发帖时,您的帖子只会查看/api/Account/Users/SelectAgent的网址。在与函数匹配时,不会考虑提交的数据,因为您没有使用Guid属性标记[FromBody]。因此,正在返回“方法不允许”错误,因为它将您的POST请求发送到您的GET方法(没有参数)。

您可以在asp.net上了解详情:

  

如果参数是“简单”类型,Web API会尝试从URI中获取值。简单类型包括.NET基元类型(int,bool,double等),以及TimeSpan,DateTime,Guid,decimal和string,以及具有可以从字符串转换的类型转换器的任何类型。 (稍后将详细介绍类型转换器。)

要解决此问题,请尝试执行以下操作之一:

  1. 更改您要提交的网址,以便在电子邮件的查询字符串中包含id

    url: '/api/Account/Users/SelectAgent?id=' + selectModel.agentId()

  2. 更改操作签名以阅读ID FromBody

    public HttpResponseMessage SelectAgent([FromBody]Guid id)

答案 1 :(得分:3)

我知道这是一个老问题,但这个答案可能对某人有所帮助。更改Action签名以读取Id FromBody:对我来说不起作用,我想知道当你有一个包含许多字段/成员的复杂类型时,将参数传递给查询字符串是多么容易。

这个问题是由于传统和基于动词的路由都不能在同一个ApiController中使用。见this link。 您可以通过向POST操作方法添加空[Route]属性来解决此问题。那是: -

 [HttpPost]
 [Route]
 public HttpResponseMessage SelectAgent(Guid id)

答案 2 :(得分:1)

如果您的帖子和获取功能具有相同的名称,它将路由到Get功能。这就是为什么你得到这个答案。今天最简单的方法是

 [HttpPost]
 [Route("api/postagent", Name ="postagent")]
 public HttpResponseMessage SelectAgent(Guid id)

只需为您的帖子功能定义路线,并在客户端为其发布 主持人+ / api / postagent例如。您可以通过此链接找到更多详细信息。

如果您通过generatin new controller创建一个api控制器,这将特别有用。预定义函数将具有get和post方法具有相同路径的结构。你需要重新定义其中一个或两个分开它们。

https://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#route-names

相关问题