web-dev-qa-db-ja.com

ここで「リクエストURIに一致するHTTPリソースが見つからなかった」のはなぜですか?

私のコントローラには次のようなコードがあります:

[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であるということです。それは大きな違いを生みますか? IamこのRESTメソッドを呼び出そうとすると、Postmanのドロップダウンから[Post]を選択します。

更新

はい、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 AP​​I呼び出しは、これと同じ方法で失敗します。他のすべて(http://localhost:21609/api/deliveries/Count, http://localhost:21609/api/deliveryitems/count, http://localhost:21609/api/department/getall)は問題なく動作します。 IOW、URIに引数がない場合、メソッドが検出されます。 areargsがある場合、そうではありません。

だからどうやらURIで引数/値を渡す方法に何か問題があります(単一の引数の場合は「?=」、2つの引数の場合は「- ?=&= ")および/またはルーティングの設定方法に問題があります。具体的には、このスタイルが機能します。

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

...一方、このスタイルはそうではありません:

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

私はこの質問をできるだけ早く賞賛します-このゴーディスクな結び目のもつれを50ポイント、今日答えた場合は100(賞金の設定前)。

更新4

ルーティングを変更して、引数のデータ型が含まれるようにしました。

[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/

...「1つ以上の必須パラメーターに値が指定されていません」で失敗し続けます。これがヒットしても:

[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> 

¡Quemon demonios!

悲しいことに、ささやくカーテンの後ろに隠れているもう1つのガーゴイルがあることを、私は微笑んで覚えています(ロビンソンジェファーズとエドガーアレンポーがレスリングしているようです)。淡々と...

更新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の1つ以上の必須パラメーターに値が指定されていません。」という表記でパッケージを送り返します。

¡Quemon 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}")]

...そして、実際に、コントローラーで一致するアクションを提供したと言うでしょう。そして、PostmanにURIとしてこれを入力するだけの場合:

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

...次に、Postmanの「URLパラメーターキー/値」インターフェイスを使用してそれらを追加すると、次のように、上記とまったく同じURLが生成されます。

enter image description here

...そしてまったく同じ結果が得られます。

もう一度言うだけです(私の「ラス・ウヴァス・デ・ラ・イラ」-風のスペイン語):¡Que demonios!

45
B. Clay Shannon

問題はPOST/GETとは関係ありませんが、RouteAttributeでパラメーターを指定する方法とのみ関係があります。これを確実にするために、サンプルに両方の動詞のサポートを追加しました。

2つの非常に単純な作業例に戻りましょう。

    [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の例は次のとおりです。

  • localhost:xxx/api/deliveryItems/dkjd; dslkf; dfk; kkklm; oeop
    • return "dkjd; dslkf; dfk; kkklm; oeop"

2番目のサンプルは、「anyString」がクエリ文字列パラメーターであることを示しています(デフォルト値が提供されているため、ここではオプションですが、デフォルト値を削除するだけで非オプションにできます)。

2番目のサンプルURLは次のとおりです。

  • localhost:xxx/api/deliveryItems?anyString = dkjd; dslkf; dfk; kkklm; oeop
    • return "dkjd; dslkf; dfk; kkklm; oeop"
  • localhost:xxx/api/deliveryItems
    • 「デフォルト」を返します

もちろん、この3番目のサンプルのように、さらに複雑にすることもできます。

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

3番目のサンプルURLの例は次のとおりです。

  • localhost:xxx/api/deliveryItems?anyString = dkjd; dslkf; dfk; kkklm; oeop
    • return "dkjd; dslkf; dfk; kkklm; oeop || anotherDefault"
  • localhost:xxx/api/deliveryItems
    • 「リクエストURIに一致するHTTPリソースが見つかりませんでした...」を返します(パラメータanyStringは必須です)
  • localhost:xxx/api/deliveryItems?anotherString = bluberb&anyString = dkjd; dslkf; dfk; kkklm; oeop
    • 「dkjd; dslkf; dfk; kkklm; oeop || bluberb」を返します
    • パラメータが逆になっていることに注意してください、重要ではありません、これは最初の例の「URLスタイル」では不可能です

いつパスセグメントまたはクエリパラメータを使用する必要がありますか?いくつかのアドバイスが既にここに与えられています: REST APIベストプラクティス:パラメーターを配置する場所?

47
Benoit74B

クエリ文字列を介してパラメータを送信するときに、[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;

4
Kunal Mukherjee

この仲間を試してみてください.

    [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);
    }
2
Egli Becerra
WebApiConfig.Register(GlobalConfiguration.Configuration); should be on top.
2
user5430808

パラメータをクエリ要素として指定するには、一意のルートをマッピングする必要があります。 RouteConfig.cs(またはWebApiConfig.cs)で以下を追加します。

config.Routes.MapHttpRoute(
            name: "MyPagedQuery",
            routeTemplate:     "api/{controller}/{action}/{firstId}/{countToFetch}",
            defaults: new { action = "GetNDepartmentsFromID" }
        );
2
ComeIn

GETサービスの場合は、POSTメソッドではなく、GETメソッドで使用する必要があります。問題はタイプの不一致です。タイプの不一致の別の例(重大度を予測するため)は、整数変数に文字列を割り当てようとしています。

1
DarkNinja955

継承したクラスを確認してください。それが単なるControllerかAPIControllerかどうか。

誤って、MVC 5コントローラーからコントローラーを作成する可能性があります。 Web API Controllerからのものでなければなりません。

1
Thriveni

別のアセンブリからRESTメソッドを呼び出す場合、すべての参照がメインプロジェクト参照と同じバージョンであることを確認する必要があります。そうしないと、コントローラーが見つかりません。

よろしく。

1
Carlos Rangel