64

我的控制器中有这样的代码:

[Route("api/deliveryitems/InsertIntoPPTData/{stringifiedRecord}")]

...我通过邮递员这样称呼它:

    http://localhost:21609/api/deliveryitems/InsertIntoPPTData?
stringifiedRecord=serNum77;tx2;siteNum2;bla2.xml;ppt_user2;tx_memo2;file_beg2;file_end2

...但是得到:

{
Message: "No HTTP resource was found that matches the request URI     
'http://localhost:21609/api/deliveryitems/InsertIntoPPTData?   stringifiedRecord=serNum77;tx2;siteNum2;bla2.xml;ppt_user2;tx_memo2;file_beg2;file_end2'."
MessageDetail: "No type was found that matches the controller named 'deliveryitems'."
}

发现以相同方式创建和调用的其他 REST 方法很好 - 为什么不是这个呢?它与其他的唯一不同之处是它是一个 HttpPost,而其他的是 HttpGet。这有那么大的不同吗?尝试调用此 REST 方法时,我从 Postman 的下拉列表中选择“发布

更新

是的,它显然与它是 Post 并在 URI 中传递 args 无关,因为我现在使用 HttpGet 方法得到了同样的东西:

{
Message: "No HTTP resource was found that matches the request URI     
'http://localhost:21609/api/department/getndeptsfromid?firstId=2&countToFetch=12'."
MessageDetail: "No action was found on the controller 'Department' that matches the request."
}

我像这样从邮递员那里调用它:

http://localhost:21609/api/department/getndeptsfromid?firstId=2&countToFetch=12

...它确实出现在我的控制器中:

[HttpGet]
[Route("api/department/getndeptsfromid/{firstId}/{countToFetch}")]
public List<Department> GetNDepartmentsFromID(int FirstId, int CountToFetch)
{
    return CCRService.GetNDepartmentsFromID(FirstId, CountToFetch);
}

更新 2

当我更改此代码时,我以为我即将解决它:

String.Format("api/department/getndeptsfromid/{0}/{1}", FirstId, CountToFetch)

...对此:

String.Format("api/department/getndeptsfromid?firstId={0}&countToFetch={1}", FirstId, CountToFetch)

...但我仍然得到相同的错误消息...

更新 3

我发现这也不起作用:

http://localhost:21609/api/delivery/invnumbyid?ID=33

......所以有一个明确的模式。我进行的每个包含 args/params 的 REST API 调用都以同样的方式失败;所有其他 ( http://localhost:21609/api/deliveries/Count, http://localhost:21609/api/deliveryitems/count, http://localhost:21609/api/department/getall) 工作正常。IOW,如果 URI 中没有参数,则发现该方法。如果有args,则不是。

因此,显然我在 URI 中传递 args/vals 的方式有问题(在单个 arg 的情况下附加“ ?= ”,在两个 args 的情况下附加“ ?=&= ”)和/或我设置路由的方式有问题。具体来说,这种风格有效:

[Route("api/Deliveries/Count")]

...而这种风格不会:

[Route("api/delivery/invnumbyid/{ID}")]

我会尽快奖励这个问题 - 这个 Gordiesque 结的解开者得 50 分,如果今天得到回答(在设置赏金之前),得 100 分。

更新 4

我更改了路由以包含 arg 的数据类型,以便:

[Route("api/delivery/invnumbyid/{ID}")]

-变成了这样:

[Route("api/delivery/invnumbyid/{ID:int}")]"

但还是失败了,咆哮道:

{
Message: "No HTTP resource was found that matches the request URI 
'http://localhost:21609/api/delivery/invnumbyid?ID=45'."
MessageDetail: "No action was found on the controller 'Delivery' that matches the request."
}

然后,“在云雀上”,我尝试将其输入 Postman:

http://localhost:21609/api/delivery/invnumbyid/45

......它奏效了!(我一直认为它需要是“ http://localhost:21609/api/delivery/invnumbyid?ID=45”)

但是 Postman 的类似尝试:

http://localhost:21609/api/department/getndeptsfromid/2/12/

...继续失败,并显示“没有为一个或多个必需参数提供值”。即使这是命中:

[HttpGet]
[Route("api/department/getndeptsfromid/{firstId}/{countToFetch}")]
public List<Department> GetNDepartmentsFromID(int FirstId, int CountToFetch)
{
    return HHSService.GetNDepartmentsFromID(FirstId, CountToFetch);
}

...并且 GetNDepartmentsFromID() 的参数具有预期的值(2 和 12)

更糟糕/更奇怪的是我http://localhost:21609/api/deliveryitems/InsertIntoPPTData/serNum77;tx2;siteNum2;bla2.xml;ppt_user2;tx_memo2;file_beg2;file_end2现在用 " " 得到的结果:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
    xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>IIS 8.0 Detailed Error - 404.0 - Not Found</title>
        <style type="text/css">
            <!-- 
body{margin:0;font-size:.7em;font-family:Verdana,Arial,Helvetica,sans-serif;} 
code{margin:0;color:#006600;font-size:1.1em;font-weight:bold;} 
.config_source code{font-size:.8em;color:#000000;} 
pre{margin:0;font-size:1.4em;word-wrap:break-word;} 
ul,ol{margin:10px 0 10px 5px;} 
ul.first,ol.first{margin-top:5px;} 
fieldset{padding:0 15px 10px 15px;word-break:break-all;} 
.summary-container fieldset{padding-bottom:5px;margin-top:4px;} 
legend.no-expand-all{padding:2px 15px 4px 10px;margin:0 0 0 -12px;} 
legend{color:#333333;;margin:4px 0 8px -12px;_margin-top:0px; 
font-weight:bold;font-size:1em;} 
a:link,a:visited{color:#007EFF;font-weight:bold;} 
a:hover{text-decoration:none;} 
h1{font-size:2.4em;margin:0;color:#FFF;} 
h2{font-size:1.7em;margin:0;color:#CC0000;} 
h3{font-size:1.4em;margin:10px 0 0 0;color:#CC0000;} 
h4{font-size:1.2em;margin:10px 0 5px 0; 
}#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS",Verdana,sans-serif; 
 color:#FFF;background-color:#5C87B2; 
}#content{margin:0 0 0 2%;position:relative;} 
.summary-container,.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;} 
.content-container p{margin:0 0 10px 0; 
}#details-left{width:35%;float:left;margin-right:2%; 
}#details-right{width:63%;float:left;overflow:hidden; 
}#server_version{width:96%;_height:1px;min-height:1px;margin:0 0 5px 0;padding:11px 2% 8px 2%;color:#FFFFFF; 
 background-color:#5A7FA5;border-bottom:1px solid #C1CFDD;border-top:1px solid #4A6C8E;font-weight:normal; 
 font-size:1em;color:#FFF;text-align:right; 
}#server_version p{margin:5px 0;} 
table{margin:4px 0 4px 0;width:100%;border:none;} 
td,th{vertical-align:top;padding:3px 0;text-align:left;font-weight:normal;border:none;} 
th{width:30%;text-align:right;padding-right:2%;font-weight:bold;} 
thead th{background-color:#ebebeb;width:25%; 
}#details-right th{width:20%;} 
table tr.alt td,table tr.alt th{} 
.highlight-code{color:#CC0000;font-weight:bold;font-style:italic;} 
.clear{clear:both;} 
.preferred{padding:0 5px 2px 5px;font-weight:normal;background:#006633;color:#FFF;font-size:.8em;} 
-->
        </style>
    </head>
    <body>
        <div id="content">
            <div class="content-container">
                <h3>HTTP Error 404.0 - Not Found</h3>
                <h4>The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.</h4>
            </div>
            <div class="content-container">
                <fieldset>
                    <h4>Most likely causes:</h4>
                    <ul>
                        <li>The directory or file specified does not exist on the Web server.</li>
                        <li>The URL contains a typographical error.</li>
                        <li>A custom filter or module, such as URLScan, restricts access to the file.</li>
                    </ul>
                </fieldset>
            </div>
            <div class="content-container">
                <fieldset>
                    <h4>Things you can try:</h4>
                    <ul>
                        <li>Create the content on the Web server.</li>
                        <li>Review the browser URL.</li>
                        <li>Check the failed request tracing log and see which module is calling SetStatus. For more information, click 
                            <a href="http://go.microsoft.com/fwlink/?LinkID=66439">here</a>. 
                        </li>
                    </ul>
                </fieldset>
            </div>
            <div class="content-container">
                <fieldset>
                    <h4>Detailed Error Information:</h4>
                    <div id="details-left">
                        <table border="0" cellpadding="0" cellspacing="0">
                            <tr class="alt">
                                <th>Module</th>
                                <td>&nbsp;&nbsp;&nbsp;IIS Web Core</td>
                            </tr>
                            <tr>
                                <th>Notification</th>
                                <td>&nbsp;&nbsp;&nbsp;MapRequestHandler</td>
                            </tr>
                            <tr class="alt">
                                <th>Handler</th>
                                <td>&nbsp;&nbsp;&nbsp;StaticFile</td>
                            </tr>
                            <tr>
                                <th>Error Code</th>
                                <td>&nbsp;&nbsp;&nbsp;0x80070002</td>
                            </tr>
                        </table>
                    </div>
                    <div id="details-right">
                        <table border="0" cellpadding="0" cellspacing="0">
                            <tr class="alt">
                                <th>Requested URL</th>
                                <td>&nbsp;&nbsp;&nbsp;http://localhost:21609/api/deliveryitems/InsertIntoPPTData/serNum77;tx2;siteNum2;bla2.xml;ppt_user2;tx_memo2;file_beg2;file_end2</td>
                            </tr>
                            <tr>
                                <th>Physical Path</th>
                                <td>&nbsp;&nbsp;&nbsp;C:\project\git\CStore\HHS.API\api\deliveryitems\InsertIntoPPTData\serNum77;tx2;siteNum2;bla2.xml;ppt_user2;tx_memo2;file_beg2;file_end2</td>
                            </tr>
                            <tr class="alt">
                                <th>Logon Method</th>
                                <td>&nbsp;&nbsp;&nbsp;Anonymous</td>
                            </tr>
                            <tr>
                                <th>Logon User</th>
                                <td>&nbsp;&nbsp;&nbsp;Anonymous</td>
                            </tr>
                            <tr class="alt">
                                <th>Request Tracing Directory</th>
                                <td>&nbsp;&nbsp;&nbsp;C:\Users\clay\Documents\IISExpress\TraceLogFiles\HHS.API</td>
                            </tr>
                        </table>
                        <div class="clear"></div>
                    </div>
                </fieldset>
            </div>
            <div class="content-container">
                <fieldset>
                    <h4>More Information:</h4> 
  This error means that the file or directory does not exist on the server. Create the file or directory and try the request again. 

                    <p>
                        <a href="http://go.microsoft.com/fwlink/?LinkID=62293&amp;IIS70Error=404,0,0x80070002,7601">View more information &raquo;</a>
                    </p>
                </fieldset>
            </div>
        </div>
    </body>
</html> 

¡

我悲伤地微笑着记得,总是在沙沙作响的窗帘后面藏着一只石像鬼(Robinson Jeffers 和 Edgar Allen Poe 似乎正在摔跤)。苍白的徘徊...

更新 5

好吧,这里换个说法:

来自 Postman,如果我使用此 URL:

http://localhost:21609/api/department/getndeptsfromid/2/12/

我把它变成了这个方法:

[HttpGet]
[Route("api/department/getndeptsfromid/{firstId}/{countToFetch}")]
public List<Department> GetNDepartmentsFromID(int FirstId, int CountToFetch)
{
    return HHSService.GetNDepartmentsFromID(FirstId, CountToFetch);
}

... FirstId 的值为 2,CountToFetch 的值为 12(正如我所期望的那样)。但随后,邮递员将我的包裹发回,并附上“ 500 No value given for one or more required parameters ” 。

¡ 这两个参数显然都通过了!

如果我使用看起来更正确的 URI:

http://localhost:21609/api/department/getndeptsfromid?firstId=2&countToFetch=12

我得到:

{
Message: "No HTTP resource was found that matches the request URI   
'http://localhost:21609/api/department/getndeptsfromid?firstId=2&countToFetch=12'."
MessageDetail: "No action was found on the controller 'Department' that matches the request."
}

然而,这是我提供的路线:

[Route("api/department/getndeptsfromid/{firstId}/{countToFetch}")]

...所以我会说我确实在控制器上提供了一个匹配的操作。顺便说一句,如果我只是将其作为 URI 输入到 Postman 中:

http://localhost:21609/api/department/getndeptsfromid

...然后使用 Postman 的“URL Parameter Key / Value”接口添加这些,它会生成与上面完全相同的 URL,如下所示:

在此处输入图像描述

...并具有完全相同的结果。

我只能再说一遍(请原谅我的“ Las Uvas de la Ira ”——灵感来自西班牙语):¡

4

12 回答 12

64

您的问题与 POST/GET 无关,而与您在RouteAttribute. 为了确保这一点,我在示例中添加了对这两个动词的支持。

让我们回到两个非常简单的工作示例。

[Route("api/deliveryitems/{anyString}")]
[HttpGet, HttpPost]
public HttpResponseMessage GetDeliveryItemsOne(string anyString)
{
    return Request.CreateResponse<string>(HttpStatusCode.OK, anyString);
}

[Route("api/deliveryitems")]
[HttpGet, HttpPost]
public HttpResponseMessage GetDeliveryItemsTwo(string anyString = "default")
{
    return Request.CreateResponse<string>(HttpStatusCode.OK, anyString);
}

第一个示例说“ anyString”是路径段参数(URL 的一部分)。

第一个示例示例 URL 是:

  • 本地主机:xxx/api/deliveryItems/dkjd;dslkf;dfk;kkklm;oeop
    • 返回"dkjd;dslkf;dfk;kkklm;oeop"

第二个示例说“ anyString”是一个查询字符串参数(此处是可选的,因为已提供默认值,但您可以通过简单地删除默认值使其成为非可选参数)。

第二个示例 URL 是:

  • 本地主机:xxx/api/deliveryItems?anyString=dkjd;dslkf;dfk;kkklm;oeop
    • 返回"dkjd;dslkf;dfk;kkklm;oeop"
  • 本地主机:xxx/api/deliveryItems
    • 返回"default"

当然,你可以让它变得更复杂,就像第三个示例一样:

[Route("api/deliveryitems")]
[HttpGet, HttpPost]
public HttpResponseMessage GetDeliveryItemsThree(string anyString, string anotherString = "anotherDefault")
{
    return Request.CreateResponse<string>(HttpStatusCode.OK, anyString + "||" + anotherString);
}

第三个示例 URL 是:

  • 本地主机:xxx/api/deliveryItems?anyString=dkjd;dslkf;dfk;kkklm;oeop
    • 返回"dkjd;dslkf;dfk;kkklm;oeop||anotherDefault"
  • 本地主机:xxx/api/deliveryItems
    • 返回“未找到与请求 URI 匹配的 HTTP 资源 ...”(参数anyString是强制性的)
  • 本地主机:xxx/api/deliveryItems?anotherString=bluberb&anyString=dkjd;dslkf;dfk;kkklm;oeop
    • 返回"dkjd;dslkf;dfk;kkklm;oeop||bluberb"
    • 请注意,参数已经颠倒了,这没关系,这对于第一个示例的“URL-style”是不可能的

什么时候应该使用路径段或查询参数?这里已经给出了一些建议: REST API 最佳实践:在哪里放置参数?

于 2014-07-22T20:07:27.417 回答
5

通过查询字符串发送参数时,您是否尝试过使用该[FromUri]属性。

这是一个例子:

[HttpGet]
[Route("api/department/getndeptsfromid")]
public List<Department> GetNDepartmentsFromID([FromUri]int FirstId, [FromUri] int CountToFetch)
{
    return HHSService.GetNDepartmentsFromID(FirstId, CountToFetch);
}

在顶部也包括这个包,using System.Web.Http;

于 2017-07-21T09:16:01.527 回答
5

试试这个伴侣,你可以像这样把它扔进身体里……

    [HttpPost]
    [Route("~/API/ChangeTheNameIfNeeded")]
    public bool SampleCall([FromBody]JObject data)
    {
        var firstName = data["firstName"].ToString();
        var lastName= data["lastName"].ToString();
        var email = data["email"].ToString();
        var obj= data["toLastName"].ToObject<SomeObject>();

        return _someService.DoYourBiz(firstName, lastName, email, obj);
    }
于 2018-08-06T13:26:22.010 回答
5

我遇到了类似的问题,并通过以下方式解决了它。该问题看起来与 Route 定义无关,而是与参数的定义有关,只需要给它一个默认值即可。

----有问题的代码:消息:“未找到与请求 URI 匹配的 HTTP 资源

    [HttpGet]
    [Route("students/list")]
    public StudentListResponse GetStudents(int? ClassId, int? GradeId)
    {
       ...
    }

----没有问题的代码。

    [HttpGet]
    [Route("students/list")]
    public StudentListResponse GetStudents(int? ClassId=null, int? GradeId=null)
    {
       ...
    }
于 2020-04-08T01:18:02.937 回答
4
WebApiConfig.Register(GlobalConfiguration.Configuration); should be on top.
于 2016-06-28T10:19:08.667 回答
4

我遇到了这个问题,如果您从另一个程序集调用您的 REST 方法,您必须确保您的所有引用都与您的主要项目引用具有相同的版本,否则将永远找不到您的控制器。

问候。

于 2018-06-28T17:10:10.113 回答
3

您需要映射唯一路由以将您的参数指定为查询元素。在 RouteConfig.cs(或 WebApiConfig.cs)中添加:

config.Routes.MapHttpRoute(
            name: "MyPagedQuery",
            routeTemplate:     "api/{controller}/{action}/{firstId}/{countToFetch}",
            defaults: new { action = "GetNDepartmentsFromID" }
        );
于 2016-12-23T01:25:11.900 回答
3

如果您重命名它,请确保控制器名称与您的 DeliveryController 相同(它不会自动更改!)。如果您也重命名项目名称,则应从 Bin 文件夹中删除对该项目的引用。不要忘记指定方法 get 或 post。

于 2019-11-13T16:15:21.170 回答
2

如果它是 GET 服务,那么您需要将它与 GET 方法一起使用,而不是 POST 方法。您的问题是类型不匹配。类型不匹配的另一个示例(从严重性角度考虑)是尝试将字符串分配给整数变量。

于 2014-07-15T22:59:41.610 回答
2

请检查您继承的类。无论是简单的 Controller 还是 APIController。

错误地,我们可能会从 MVC 5 控制器创建一个控制器。它应该来自 Web API 控制器。

于 2018-07-17T11:44:09.647 回答
1

对于 .net web api,请注意,您的控制器必须从 ApiController 继承,否则,您将收到此错误。

于 2022-01-12T11:52:27.413 回答
1

确保:

  1. 控制器名称拼写正确
  2. 具有正确的 POST/GET 指令
  3. 您没有遗漏 URL 中的任何参数

最后一个是给我带来麻烦的。

于 2022-01-20T14:22:38.107 回答