8

アップデート

私の最初の仮定は、オプションのパラメーターが問題の原因であるというものでした。それは正しくないようです。代わりに、複数のアクション メソッドの 1 つに、いくつかのパラメーターの null 許容値型 (例: int? ) が含まれている場合、複数のアクション メソッドに問題があるように見えます。

私は Visual Studio 2012 RC を使用しており、Web API を使い始めたばかりです。問題が発生し、「要求に一致するアクションがコントローラ 'Bars' で見つかりませんでした」というエラーが表示されました。

Barsコントローラーを手に入れました。オプションのパラメーターを受け取る Get() メソッドがあります。

public IEnumerable<string> Get(string h, string w = "defaultWorld", int? z=null)
{
    if (z != 0)
        return new string[] { h, w, "this is z: " + z.ToString() };
    else
       return new string[] { h, w };
}

だから、私は次のURLでそれをテストします

  • /api/bars?h=こんにちは
  • /api/bars?h=こんにちは&w=世界
  • /api/bars?h=hello&w=world&z=15

そして、それは3つすべてに機能します。

次に、別の Get() メソッドを追加します。今回は id パラメーターを 1 つ指定します。

 public string Get(int id)
 {
     return "value";
 }

URL をもう一度テストします。今度は /api/bars?h=hello&w=world と api/bars?h=hello が失敗します。エラー メッセージは、「要求に一致するアクションがコントローラ 'Bar' に見つかりませんでした」です。

何らかの理由で、これら 2 つの方法はうまく連携しません。削除するGet(int id)と動作します。intに変更したら?z を文字列 z に変換すると動作します (ただし、アクション メソッド内のオブジェクトを変換する必要があります!)。

Web API がこれを行っているのはなぜですか? これはバグですか、それとも仕様ですか?

どうもありがとう。

4

3 に答える 3

3

私はこの問題の本当の答えをまだ見つけていません(なぜWeb APIがこれを行うのですか)が、オーバーロードされたGet()を可能にする回避策があります。秘訣は、パラメータ値をオブジェクトにラップすることです。

public class Foo
{
    public string H { get; set; }
    public string W { get; set; }
    public int? Z { get; set; }
}

そして、バーコントローラーに変更します

public IEnumerable<string> Get([FromUri] Foo foo)
{
    if (foo.Z.HasValue)
        return new string[] { foo.H, foo.W, "this is z: " + foo.Z.ToString() };
    else
        return new string[] { foo.H, foo.W, "z does not have a value" };
}

[FromUri]WebAPIはデフォルトではURIパラメータを使用して「複雑な」オブジェクトを形成しないため、必要です。一般的な考え方は、複雑なオブジェクトは<form>GETリクエストではなく、アクションから発生しているというものです。

Web APIがこのように動作する理由と、これが実際にバグなのか意図された動作なのかを引き続き確認します。

于 2012-07-11T15:07:58.007 に答える
2

ルートにアクションパラメータを追加することで、WEBAPIControllerメソッドをオーバーロードできます。

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

ルートにこの変更を加えると、次のようなメソッドを呼び出すことができます。

/api/bars/get?id=1
/api/bars/get?h=hello&w=world&z=15

この助けを願っています。

オマール

于 2012-07-10T17:40:48.130 に答える
2

問題は解決しましたが、追加の質問が残ります。問題は、オーバーロードされたActionメソッドがオプションのパラメーターに問題を抱えていることであるように思われます。

だから新しい質問はなぜそうなのかということですが、私はそれを私よりも低いレベルの人に任せます;)

しかし、これは朗報です。あなたが報告した問題が気に入らなかったので、複雑なタイプのルートを使用することは、知っておくと便利ですが、単なるジェリーリグの修正であり、WebApiで何かがどのように機能しているかについてはほとんど反映されません。したがって、良いニュースは、この問題が発生した場合、オプションのパラメータを削除するだけで解決され、古き良きオーバーロードルートを実行することです。良いニュースですが、これは決してジェリーリグの修正ではないため、オプションのパラメータの利便性が少し失われます。

public class BarsController : ApiController
{
    public string Get(int id)
    {
        return "value";
    }

    public IEnumerable<string> Get(string h)
    {
        return Get(h, null, null);
    }

    public IEnumerable<string> Get(string h, string w)
    {
        return Get(h, w, null);
    }

    public IEnumerable<string> Get(string h, string w, int? z) 
    {
        if (z != 0)
            return new string[] { h, w, "this is z: " + z.ToString() };
        else
            return new string[] { h, w };
    }
}

乾杯

于 2012-08-01T05:52:21.113 に答える