J'ai le code dans mon contrôleur comme suit:
[Route("api/deliveryitems/InsertIntoPPTData/{stringifiedRecord}")]
... et je l'appelle via Postman comme suit:
http://localhost:21609/api/deliveryitems/InsertIntoPPTData?
stringifiedRecord=serNum77;tx2;siteNum2;bla2.xml;ppt_user2;tx_memo2;file_beg2;file_end2
... mais obtenez:
{
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'."
}
D'autres méthodes REST qui sont créées et appelées de la même manière se trouvent très bien - pourquoi pas celle-ci? La seule chose qu'il n'a pas en commun avec les autres, c'est qu'il s'agit d'un HttpPost, alors que les autres sont HttpGet. Est-ce que cela fait une grande différence? Je suis en sélectionnant "Post" dans le menu déroulant de Postman lorsque vous essayez d'appeler cette méthode REST.
Oui, cela n'a apparemment rien à voir avec le fait d'être une publication et de passer des arguments dans l'URI, car je reçois la même chose maintenant avec une méthode 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."
}
Je l'appelle de postier comme suit:
http://localhost:21609/api/department/getndeptsfromid?firstId=2&countToFetch=12
... et il apparaît bien dans mon contrôleur:
[HttpGet]
[Route("api/department/getndeptsfromid/{firstId}/{countToFetch}")]
public List<Department> GetNDepartmentsFromID(int FirstId, int CountToFetch)
{
return CCRService.GetNDepartmentsFromID(FirstId, CountToFetch);
}
Je pensais être sur le point de le résoudre quand j'ai changé ce code:
String.Format("api/department/getndeptsfromid/{0}/{1}", FirstId, CountToFetch)
...pour ça:
String.Format("api/department/getndeptsfromid?firstId={0}&countToFetch={1}", FirstId, CountToFetch)
... mais j'ai toujours la même erreur msg ...
Je trouve que cela aussi ne fonctionne pas:
http://localhost:21609/api/delivery/invnumbyid?ID=33
... et donc il y a un modèle défini. CHAQUE REST appel API que je fais et qui contient args/params échoue de la même manière; tous les autres (http://localhost:21609/api/deliveries/Count, http://localhost:21609/api/deliveryitems/count, http://localhost:21609/api/department/getall
) fonctionnent parfaitement. IOW, s'il n'y a pas d'argument dans l'URI, la méthode est découverte. S'il y a are args, ce n'est pas le cas.
Donc, apparemment, il y a quelque chose qui cloche dans la façon dont je passe les arguments args/vals dans l'URI (en ajoutant "? = " dans le cas d'un argument unique et, dans le cas de deux arguments "? = = & = ") et/ou quelque chose ne va pas dans la configuration du routage. Plus précisément, ce style fonctionne:
[Route("api/Deliveries/Count")]
... alors que ce style ne:
[Route("api/delivery/invnumbyid/{ID}")]
Je vais bountifier cette question dès que possible - 50 points au démêlant de ce nœud gordiesque, et 100 si on lui répond aujourd'hui (avant la mise en place de la prime).
J'ai changé le routage pour inclure le type de données de l'argument de sorte que:
[Route("api/delivery/invnumbyid/{ID}")]
-comme ceci:
[Route("api/delivery/invnumbyid/{ID:int}")]"
Mais ça a quand même échoué, grognant:
{
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."
}
Puis, "sur une alouette", j'ai essayé d'entrer ceci dans Postman:
http://localhost:21609/api/delivery/invnumbyid/45
... et ça a fonctionné! (Je pensais que ça devait être "http://localhost:21609/api/delivery/invnumbyid?ID=45
")
Mais une tentative similaire dans Postman:
http://localhost:21609/api/department/getndeptsfromid/2/12/
... continue à échouer avec "Aucune valeur donnée pour un ou plusieurs paramètres requis." même si cela est touché:
[HttpGet]
[Route("api/department/getndeptsfromid/{firstId}/{countToFetch}")]
public List<Department> GetNDepartmentsFromID(int FirstId, int CountToFetch)
{
return HHSService.GetNDepartmentsFromID(FirstId, CountToFetch);
}
... et les arguments de GetNDepartmentsFromID () ont les valeurs attendues (2 et 12)
Encore pire/plus étrange est le résultat que je reçois avec "http://localhost:21609/api/deliveryitems/InsertIntoPPTData/serNum77;tx2;siteNum2;bla2.xml;ppt_user2;tx_memo2;file_beg2;file_end2
" maintenant:
<!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 démonios!
Je me rappelle tristement avec le sourire souriant qu’il y a toujours une gargouille de plus cachée derrière le rideau bruissant (où Robinson Jeffers et Edgar Allen Poe semblent être en lutte). Vaguement flânant ...
Ok, ici c'est dit différemment:
De Postman, si j'utilise cette URL:
http://localhost:21609/api/department/getndeptsfromid/2/12/
Je le fais dans cette méthode:
[HttpGet]
[Route("api/department/getndeptsfromid/{firstId}/{countToFetch}")]
public List<Department> GetNDepartmentsFromID(int FirstId, int CountToFetch)
{
return HHSService.GetNDepartmentsFromID(FirstId, CountToFetch);
}
... où la valeur de FirstId est 2 et la valeur de CountToFetch est 12 (comme je l’attendrais). Mais ensuite, Postman renvoie mon colis avec la notation "500 Aucune valeur n’est donnée pour un ou plusieurs paramètres obligatoires."
¡Que démonios! Les deux paramètres ont évidemment été passés!
Si j'utilise un URI, cela semblerait plus correct:
http://localhost:21609/api/department/getndeptsfromid?firstId=2&countToFetch=12
Je reçois:
{
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."
}
C'est pourtant l'itinéraire que j'ai fourni:
[Route("api/department/getndeptsfromid/{firstId}/{countToFetch}")]
... et je dirais donc que, en fait, j'ai fourni une action correspondante sur le contrôleur.
http://localhost:21609/api/department/getndeptsfromid
... et utilisez ensuite l'interface "URL Parameter Key/Value" de Postman pour les ajouter, il génère exactement la même URL que ci-dessus, comme on peut le voir ici:
... et avec exactement le même résultat.
Je ne peux que le répéter (pardonnez mon "Las Uvas de la Ira" - inspiré de l'espagnol):¡Que démonios!
Vos problèmes n'ont rien à voir avec POST/GET, mais uniquement sur la manière de spécifier des paramètres dans RouteAttribute. Pour garantir cela, j'ai ajouté la prise en charge des deux verbes dans mes exemples.
Revenons à deux exemples de travail très simples.
[Route("api/deliveryitems/{anyString}")]
[HttpGet, HttpPost]
public HttpResponseMessage GetDeliveryItemsOne(string anyString)
{
return Request.CreateResponse<string>(HttpStatusCode.OK, anyString);
}
Et
[Route("api/deliveryitems")]
[HttpGet, HttpPost]
public HttpResponseMessage GetDeliveryItemsTwo(string anyString = "default")
{
return Request.CreateResponse<string>(HttpStatusCode.OK, anyString);
}
Le premier exemple indique que "anyString" est un paramètre de segment de chemin (une partie de l'URL).
Le premier exemple d’URL est:
Le deuxième exemple indique que "anyString" est un paramètre de chaîne de requête (facultatif ici car une valeur par défaut a été fournie, mais vous pouvez le rendre non facultatif en supprimant simplement la valeur par défaut).
Le deuxième exemple d’URL est:
Bien sûr, vous pouvez le rendre encore plus complexe comme avec ce troisième exemple:
[Route("api/deliveryitems")]
[HttpGet, HttpPost]
public HttpResponseMessage GetDeliveryItemsThree(string anyString, string anotherString = "anotherDefault")
{
return Request.CreateResponse<string>(HttpStatusCode.OK, anyString + "||" + anotherString);
}
Le troisième exemple d’URL est:
Quand faut-il utiliser un segment de chemin ou des paramètres de requête? Quelques conseils ont déjà été donnés ici: REST API Meilleures pratiques: où placer les paramètres?
Avez-vous essayé d'utiliser l'attribut [FromUri]
lors de l'envoi de paramètres via la chaîne de requête?.
Voici un exemple:
[HttpGet]
[Route("api/department/getndeptsfromid")]
public List<Department> GetNDepartmentsFromID([FromUri]int FirstId, [FromUri] int CountToFetch)
{
return HHSService.GetNDepartmentsFromID(FirstId, CountToFetch);
}
Incluez également ce paquet en haut, using System.Web.Http;
WebApiConfig.Register(GlobalConfiguration.Configuration); should be on top.
Vous devez mapper la route unique pour spécifier vos paramètres en tant qu'éléments de requête. Dans RouteConfig.cs (ou WebApiConfig.cs), ajoutez:
config.Routes.MapHttpRoute(
name: "MyPagedQuery",
routeTemplate: "api/{controller}/{action}/{firstId}/{countToFetch}",
defaults: new { action = "GetNDepartmentsFromID" }
);
S'il s'agit d'un service GET, vous devez alors l'utiliser avec une méthode GET, pas avec une méthode POST. Votre problème est une incompatibilité de type. Un exemple différent d'incompatibilité de type (pour mettre la gravité en perspective) tente d'affecter une chaîne à une variable entière.
Veuillez vérifier la classe dont vous avez hérité. Que ce soit simplement contrôleur ou APIController.
Par erreur, nous pourrions créer un contrôleur à partir du contrôleur MVC 5. Cela devrait provenir de Web API Controller.
J'ai eu ce problème. Si vous appelez vos méthodes REST depuis un autre assemblage, vous devez vous assurer que toutes vos références ont la même version que vos références de projet principales, sinon vous ne trouverez jamais vos contrôleurs.
Cordialement.
Essayez ce compagnon, vous pouvez le jeter dans le corps comme si ...
[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);
}