1

次の URL にアクセスしようとしています。

http://localhost:2727/api/SiteApi/Get?campaignId=2

構成は次のとおりです。

config.Routes.MapHttpRoute(
    name: "DetailedApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

マップしようとしているアクション

public class SiteApiController : ApiController
{
    ...
    public IEnumerable<Site> GetByCampaignId(int campaignId)
    {
        ...
        return sites;   
    }      
}

これは現在、「アクションが見つかりません」を返します。ただし、ルートの順序を入れ替えると、Url は機能します。これは一致があったことを意味します。

質問: 私の理解では、ルーティングが最初のルートと一致しない場合、2 番目のルートにフォールバックします。間違ったルートにマッピングされているかどうかは理解できますが、どのように注文しても「一致が見つかりませんでした」などのエラーにはなりません。

私は何かを逃したことがありますか?

4

4 に答える 4

4

更新しました

良いリソース: http://msdn.microsoft.com/en-us/library/cc668201(v=vs.100).aspx

ルート マッチングは、コレクション内の最初のルートから最後のルートまで試行されます。一致が発生すると、それ以上のルートは評価されません。一般に、最も具体的なルート定義から最も具体的でないルート定義の順にルートを Routes プロパティに追加します。

「アクションが見つかりません」と表示される理由は、最初のルートが一致するためです。メソッドに名前を付けているため、アクション Get を見つけることができませんGetByCampaignId

http://localhost:2727/api/SiteApi/Get?campaignId=2

したがって、あなたの理解は正しいですが、URL は最初のルートと一致します (アクションが見つからないだけです)。

これにより、アクションがメソッドにマップされます

[ActionName("Get")]
public IEnumerable<Site> GetByCampaignId(int campaignId)
{

}

または単にあなたのURLを

http://localhost:2727/api/SiteApi/GetByCampaignId?campaignId=2

ルートをモデル化する方法

URL から「Get」を削除します。

クエリ文字列で CampaignId を指定する必要があるようです。

属性なしで GetByCampaignId(int CampaignId) を宣言した[FromUri]ため、campaignId はパスにあると見なされます。つまり、現状では、このメソッドは /api/siteapi/1 に一致します。

CampaignId がオプションの場合、メソッドのシグネチャを次のように変更します。

public IEnumerable<Site> GetByCampaignId([FromUri]int? campaignId = null)
{
    if(campaignId.HasValue)
    {
       //....
    }
    return sites;   
}   

ルートに CampaignId が必須である場合は、メソッド シグネチャを次のように変更します。

public IEnumerable<Site> GetByCampaignId([FromUri]int campaignId)
{
    return sites;   
}   
于 2012-12-06T09:51:59.163 に答える
2

あなたは物事を複雑にしすぎていると思います。デフォルトルートを使用してください。

あなたのURLはGet部分を必要としません:

http://localhost:2727/api/SiteApi/Get?campaignId=2

かもね

http://localhost:2727/api/SiteApi/?campaignId=2

メソッドの名前にGetが含まれているため、HTTP GETリクエストに応答します(慣例は適切です:http ://www.asp.net/web-api/overview/web-api-routing-and-actions/routing -in-aspnet-web-api)。アクションパラメータ「campaignId」が表示され、「ああ、そのアクションに移動します」と表示されます。

public IEnumerable<Site> GetByCampaignId(int campaignId)

ルートを入れ替えると、デフォルトルートが開始されて勝ちました。

追加の「DetailedApi」ルートは必要ありません、imho。

于 2012-12-06T01:59:39.540 に答える
1

これを使用することをお勧めします:

http://nuget.org/packages/routedebugger

ルートのデバッグに役立ちます。

質問していないことはわかっていますが、サンプル URI は RESTful ではありません。

2 番目のルートに一致させるには、次の URI にヒットしてみてください。

http:// localhost:2727/api/SiteApi/Get/2

「2」アクションがなく、2 番目のマッピングにフォールバックするため、最初のマッピングはこのルートをキャッチしないでください。しかし、これが問題を引き起こしていることがわかりました。私はあなたのマッピングを使用しません。私見、あなたは次と同じことを達成しようとしています。

        config.Routes.MapHttpRoute(
          name: "DetailedApi",
          routeTemplate: "api/{controller}/{id}/{action}",
          defaults: new { id = RouteParameter.Optional }
        );
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
于 2012-12-06T01:25:53.630 に答える
0

上記のすべての回答に感謝します。それらのいくつかは非常に興味深いものですが、それらは私が実際に探しているものではありません。

基本的に、私の質問は URI をどのようにマッピングすべきかではなく、正しいルートにマッピングされない理由です。幸いなことに、いくつかのテストを行った後、答えを見つけました。

では、なぜ「アクションが見つかりません」なのですか?単純に最初のルートと一致したからです。これは予想外でした。Id はオプションに設定されているため、2 つのパラメーターを持つ任意のルートに一致します。これが、"SiteAPI" がコントローラーにマップされ、"Get" がアクションにマップされる理由です。この場合、campaignId はクエリ文字列に含まれているため、URL をマップしようとすると無視されます。

ルーティングには他にも言及していない部分がありますが、これで十分です。詳細については、Mark Jones の回答を参照してください。

于 2012-12-06T10:39:29.990 に答える