我的控制器中有代码如下:
[Route("api/deliveryitems/InsertIntoPPTData/{stringifiedRecord}")]
......我正在通过Postman这样称呼它:
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);
}
当我更改此代码时,我以为我即将解决它:
String.Format("api/department/getndeptsfromid/{0}/{1}", FirstId, CountToFetch)
......对此:
String.Format("api/department/getndeptsfromid?firstId={0}&countToFetch={1}", FirstId, CountToFetch)
......但我仍然得到同样的错误信息......
我发现这也不起作用:
http://localhost:21609/api/delivery/invnumbyid?ID=33
......所以有一个明确的模式。我做的每个REST API调用包含args / params以同样的方式失败;所有其他人(http://localhost:21609/api/deliveries/Count, http://localhost:21609/api/deliveryitems/count, http://localhost:21609/api/department/getall
)工作得很好。 IOW,如果URI中没有args,则会发现该方法。如果是 args,则不是。
显然,我在URI中传递args / vals有什么不对(在单个arg的情况下附加“?= ”,在两个args的情况下“?=&amp; = ”)和/或我如何设置路由有问题。具体来说,这种风格有效:
[Route("api/Deliveries/Count")]
......而这种风格不是:
[Route("api/delivery/invnumbyid/{ID}")]
我会尽快提出这个问题 - 50点指向这个Gordiesque结的解开者,如果它今天得到回答(在设置赏金之前)则为100点。
我更改了路由以包含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
”)
但邮差中的类似尝试:
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()的参数具有预期的vals(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> 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 demonios!
我遗憾地微笑着记得,在沙沙窗帘后面总是还有一个石像鬼藏在其中(Robinson Jeffers和Edgar Allen Poe似乎正在摔跤)。苍白的游荡......
好的,这里的说法不同:
来自邮递员,如果我使用此网址:
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没有给出一个或多个必需参数的值。 ”
¡Que demonios!两个参数都明显通过了!
如果我使用看似更正确的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:
http://localhost:21609/api/department/getndeptsfromid
...然后使用Postman的“URL参数键/值”界面添加它们,它生成与上面完全相同的URL,如下所示:
......并且结果完全相同。
我只能再说一遍(原谅我的“ Las Uvas de la Ira ” - 启发西班牙语): ¡Que demonios! < / p>
答案 0 :(得分:44)
您的问题与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);
}
第一个样本说&#34; anyString&#34;是路径段参数(URL的一部分)。
第一个示例示例网址为:
第二个样本说&#34; anyString&#34;是一个查询字符串参数(此处可选,因为已提供默认值,但您可以通过简单地删除默认值使其成为非可选项。)
第二个示例示例网址为:
当然,你可以使它变得更复杂,就像第三个样本一样:
[Route("api/deliveryitems")]
[HttpGet, HttpPost]
public HttpResponseMessage GetDeliveryItemsThree(string anyString, string anotherString = "anotherDefault")
{
return Request.CreateResponse<string>(HttpStatusCode.OK, anyString + "||" + anotherString);
}
第三个示例示例网址为:
何时应使用路径段或查询参数?这里已经给出了一些建议: REST API Best practices: Where to put parameters?
答案 1 :(得分:4)
您是否在通过查询字符串发送参数时尝试使用template<class C>
struct Named { static const char* name; };
template<class C>
const char* Named<C>::name = typeid(C).name(); // fill as you wish
template<class N>
void print() { cout<< N::name <<endl;}
...
print<Named<int>>();
属性。
以下是一个例子:
[FromUri]
将此套餐也包含在顶部,[HttpGet]
[Route("api/department/getndeptsfromid")]
public List<Department> GetNDepartmentsFromID([FromUri]int FirstId, [FromUri] int CountToFetch)
{
return HHSService.GetNDepartmentsFromID(FirstId, CountToFetch);
}
答案 2 :(得分:4)
我得到了类似的问题,并通过以下方法解决了这个问题。 该问题看起来与Route定义无关,但与参数的定义有关,只需要为其提供默认值即可。
----有问题的代码:消息:“未找到与请求URI匹配的HTTP资源
setState((){
_user.count = docs.documents.last.data["count"];
)};
----没有问题的代码。
[HttpGet]
[Route("students/list")]
public StudentListResponse GetStudents(int? ClassId, int? GradeId)
{
...
}
答案 3 :(得分:2)
WebApiConfig.Register(GlobalConfiguration.Configuration); should be on top.
答案 4 :(得分:2)
您需要映射唯一路径以将参数指定为查询元素。在RouteConfig.cs(或WebApiConfig.cs)中添加:
config.Routes.MapHttpRoute(
name: "MyPagedQuery",
routeTemplate: "api/{controller}/{action}/{firstId}/{countToFetch}",
defaults: new { action = "GetNDepartmentsFromID" }
);
答案 5 :(得分:2)
只要重命名控制器名称,请确保它与您的DeliveryController相同(它不会自动更改!)。 如果您也重命名了项目名称,则应从Bin文件夹中删除对该项目的引用。 不要忘记指定get或post方法。
答案 6 :(得分:1)
如果是GET服务,则需要使用GET方法,而不是POST方法。您的问题是类型不匹配。类型不匹配的另一个例子(将严重性放入透视图)是尝试将字符串分配给整数变量。
答案 7 :(得分:1)
我遇到了这个问题,如果您要从另一个程序集调用REST方法,则必须确保所有引用都具有与主项目引用相同的版本,否则将永远找不到您的控制器。
致谢。
答案 8 :(得分:1)
请检查您继承的类。无论是简单的Controller还是APIController。
由于错误,我们可能会从MVC 5控制器创建一个控制器。它应该来自Web API控制器。
答案 9 :(得分:1)
试试这个伴侣,你可以像这样把它夹在体内……
[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);
}