为啥这里“找不到与请求 URI 匹配的 HTTP 资源”?
Posted
技术标签:
【中文标题】为啥这里“找不到与请求 URI 匹配的 HTTP 资源”?【英文标题】:Why is it that "No HTTP resource was found that matches the request URI" here?为什么这里“找不到与请求 URI 匹配的 HTTP 资源”? 【发布时间】:2014-09-06 07:24:01 【问题描述】:我的控制器中有这样的代码:
[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 中传递参数无关,因为我现在使用 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 中没有参数,则发现该方法。如果有有个参数,那就没有。
显然,我在 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">
<!--
bodymargin:0;font-size:.7em;font-family:Verdana,Arial,Helvetica,sans-serif;
codemargin:0;color:#006600;font-size:1.1em;font-weight:bold;
.config_source codefont-size:.8em;color:#000000;
premargin:0;font-size:1.4em;word-wrap:break-word;
ul,olmargin:10px 0 10px 5px;
ul.first,ol.firstmargin-top:5px;
fieldsetpadding:0 15px 10px 15px;word-break:break-all;
.summary-container fieldsetpadding-bottom:5px;margin-top:4px;
legend.no-expand-allpadding:2px 15px 4px 10px;margin:0 0 0 -12px;
legendcolor:#333333;;margin:4px 0 8px -12px;_margin-top:0px;
font-weight:bold;font-size:1em;
a:link,a:visitedcolor:#007EFF;font-weight:bold;
a:hovertext-decoration:none;
h1font-size:2.4em;margin:0;color:#FFF;
h2font-size:1.7em;margin:0;color:#CC0000;
h3font-size:1.4em;margin:10px 0 0 0;color:#CC0000;
h4font-size:1.2em;margin:10px 0 5px 0;
#headerwidth:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS",Verdana,sans-serif;
color:#FFF;background-color:#5C87B2;
#contentmargin:0 0 0 2%;position:relative;
.summary-container,.content-containerbackground:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;
.content-container pmargin:0 0 10px 0;
#details-leftwidth:35%;float:left;margin-right:2%;
#details-rightwidth:63%;float:left;overflow:hidden;
#server_versionwidth: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 pmargin:5px 0;
tablemargin:4px 0 4px 0;width:100%;border:none;
td,thvertical-align:top;padding:3px 0;text-align:left;font-weight:normal;border:none;
thwidth:30%;text-align:right;padding-right:2%;font-weight:bold;
thead thbackground-color:#ebebeb;width:25%;
#details-right thwidth:20%;
table tr.alt td,table tr.alt th
.highlight-codecolor:#CC0000;font-weight:bold;font-style:italic;
.clearclear:both;
.preferredpadding: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> IIS Web Core</td>
</tr>
<tr>
<th>Notification</th>
<td> MapRequestHandler</td>
</tr>
<tr class="alt">
<th>Handler</th>
<td> StaticFile</td>
</tr>
<tr>
<th>Error Code</th>
<td> 0x80070002</td>
</tr>
</table>
</div>
<div id="details-right">
<table border="0" cellpadding="0" cellspacing="0">
<tr class="alt">
<th>Requested URL</th>
<td> 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> 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> Anonymous</td>
</tr>
<tr>
<th>Logon User</th>
<td> Anonymous</td>
</tr>
<tr class="alt">
<th>Request Tracing Directory</th>
<td> 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&IIS70Error=404,0,0x80070002,7601">View more information »</a>
</p>
</fieldset>
</div>
</div>
</body>
</html>
¡Que恶魔!
我悲伤地微笑着记得,总是有一只石像鬼躲在沙沙作响的窗帘后面(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(正如我所期望的那样)。但是,Postman 将我的包裹发回,并附上“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”-灵感来自西班牙语):¡Que demoios!
【问题讨论】:
“500 No value given for an or more required parameters”是否有可能是与数据库相关的错误?所以 MVC 正确地路由了你的请求,但是在 HHSService.GetNDepartmentsFromID(FirstId, CountToFetch) 方法中发生了错误。 【参考方案1】:您的问题与 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 Best practices: Where to put parameters?
【讨论】:
将“||”夹在多个参数之间是常态,还是只是您碰巧做的事情? 它是“无”,我只是习惯用它来输出带有明显分隔符的单个字符串。 “||”只是比“|”更明显。在方法内部做了什么并不重要。这里通过连接字符串来构建一个 HttpResponse,但你可以做任何其他事情。 谢谢伯努瓦。.NET Web API
中的什么创建了这些默认错误消息?实体框架会自动创建这些吗?我试图避免使用我自己的服务器端错误处理功能来代替此类消息。【参考方案2】:
您是否尝试在通过查询字符串发送参数时使用[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;
【讨论】:
【参考方案3】:试试这个伴侣,你可以像这样把它扔进身体里……
[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);
【讨论】:
【参考方案4】:我遇到了类似的问题,并通过以下方式解决了它。 这个问题看起来与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)
...
【讨论】:
【参考方案5】:WebApiConfig.Register(GlobalConfiguration.Configuration); should be on top.
【讨论】:
这个和GlobalConfiguration.Configure(WebApiConfig.Register);
一样吗?
节省了我的一天,我使用 Telerik Reporting 并且在 WebApiConfig.Register(GlobalConfiguration.Configuration);
之前调用了 ReportsControllerConfiguration.RegisterRoutes(GlobalConfiguration.Configuration);
。把它放回顶部对我有用。【参考方案6】:
我遇到了这个问题,如果您从另一个程序集调用您的 REST 方法,您必须确保您的所有引用与您的主要项目引用具有相同的版本,否则将永远找不到您的控制器。
问候。
【讨论】:
【参考方案7】:您需要映射唯一路由以将您的参数指定为查询元素。在 RouteConfig.cs(或 WebApiConfig.cs)中添加:
config.Routes.MapHttpRoute(
name: "MyPagedQuery",
routeTemplate: "api/controller/action/firstId/countToFetch",
defaults: new action = "GetNDepartmentsFromID"
);
【讨论】:
为我工作!谢谢!【参考方案8】:如果您重命名它,请确保控制器名称与您的 DeliveryController 相同(它不会自动更改!)。 如果您也重命名项目名称,则应从 Bin 文件夹中删除对该项目的引用。 不要忘记指定方法 get 或 post。
【讨论】:
【参考方案9】:如果它是 GET 服务,那么您需要将其与 GET 方法一起使用,而不是 POST 方法。您的问题是类型不匹配。类型不匹配的另一个示例(从严重性角度考虑)是尝试将字符串分配给整数变量。
【讨论】:
这是一个帖子,虽然我是在 URI 中传递要发布的数据【参考方案10】:请检查您继承的类。不管是单纯的Controller还是APIController。
我们可能会错误地从 MVC 5 控制器创建控制器。它应该来自 Web API 控制器。
【讨论】:
【参考方案11】:对于.net web api,请注意,你的控制器必须继承自ApiController,否则,你会得到这个错误。
【讨论】:
【参考方案12】:确保:
-
控制器名称拼写正确
具有正确的 POST/GET 指令
您没有遗漏 URL 中的任何参数
最后一个是给我带来麻烦的。
【讨论】:
以上是关于为啥这里“找不到与请求 URI 匹配的 HTTP 资源”?的主要内容,如果未能解决你的问题,请参考以下文章