27

私はWeb APIを使用していますが、これは初めてです。ルーティングの問題で立ち往生しています。次のアクションを持つコントローラーがあります。

    // GET api/Ceremony
    public IEnumerable<Ceremony> GetCeremonies()
    {
        return db.Ceremonies.AsEnumerable();
    }

    // GET api/Ceremony/5
    public Ceremony GetCeremony(int id)
    {
        Ceremony ceremony = db.Ceremonies.Find(id);
        return ceremony;
    }

    public IEnumerable<Ceremony> GetFilteredCeremonies(Search filter)
    {
        return filter.Ceremonies();
    }

アクションをコントローラーに追加したときに問題が発生しましたGetFilteredCeremonies。アクションへの ajax 呼び出しを行うときにこれを追加した後GetCeremonies、次のメッセージで例外を返します。

"Message":"An error has occurred.","ExceptionMessage":"Multiple actions were 
 found that match the request

参考までに: パラメータSearchは、プロパティと関数名 Ceremonies を含む Model クラスです。

編集

ルート:

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

8 に答える 8

22

ルートを使用し、メソッドGET / POST / DELETE / PUTapi/{controller}/{id}に基づいてアクションを解決しようとするRESTサービスを使用する必要がない場合は、ルートを従来のMVCルートに変更できます。これで問題が解決します。api/{controller}/{action}/{id}

于 2012-11-10T06:27:25.353 に答える
8

ここでの問題は、2 つのGetメソッドが解決されapi/Ceremony、MVC がパラメーターのオーバーロードを許可しないことです。この種の問題の簡単な回避策 (必ずしも推奨される方法ではありません) は、idパラメーターを null 可能にすることです。

// GET api/Ceremony
public IEnumerable<Ceremony> GetCeremonies(int? id)
{
    if (id.HasValue)
    {
        Ceremony ceremony = db.Ceremonies.Find(id);
        return ceremony;
    }
    else
    {
        return db.Ceremonies.AsEnumerable();
    }
}

ただし、単一のセレモニーをクエリしようとすると、アイテムが 1 つの場合、セレモニーのリストが返されます。それを受け入れることができれば、それが解決策になる可能性があります。

推奨される解決策は、パスを正しいアクションに適切にマップすることです。

context.Routes.MapHttpRoute(
    name: "GetAllCeremonies",
    routeTemplate: "api/{controller}",
    defaults: new { action = "GetCeremonies" }
);

context.Routes.MapHttpRoute(
    name: "GetSingleCeremony",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { action = "GetCeremony", id = UrlParameter.Optional }
);
于 2012-11-08T14:47:39.453 に答える
6

幸いなことに、最近の WEB API2 ではAttribute Routingを使用できます。Microsoft は大規模なオープン ソース化を進めており、Tim McCall という名前のウィザードがコミュニティから貢献しました。したがって、2013 年末から 2014 年初頭にかけて[Route("myroute")]、WEB API メソッドのような属性を追加できるようになりました。以下のコード例を参照してください。

それでも - 私が見つけたように - 必ずSystem.Web.Http.Routeand NOTを使用する必要がありSystem.Web.Mvc.Routeます。そうしないと、エラー メッセージが表示されますMultiple actions were found that match the request

using System.Web.Http;
...

[Route("getceremonies")]
[HttpGet]
// GET api/Ceremony
public IEnumerable<Ceremony> GetCeremonies()
{
    return db.Ceremonies.AsEnumerable();
}

[Route("getceremony")]
[HttpGet]
// GET api/Ceremony/5
public Ceremony GetCeremony(int id)
{
    Ceremony ceremony = db.Ceremonies.Find(id);
    return ceremony;
}

[Route("getfilteredceremonies")]
[HttpGet]
public IEnumerable<Ceremony> GetFilteredCeremonies(Search filter)
{
    return filter.Ceremonies();
}
于 2015-11-11T01:18:29.900 に答える
3

これが私のコントローラーです:

public class PhoneFeaturesController : ApiController
{
    public List<PhoneFeature> GetbyPhoneId(int id)
    {
        var repository = new PhoneFeatureRepository();
        return repository.GetFeaturesByPhoneId(id);
    }

    public PhoneFeature GetByFeatureId(int id)
    {
        var repository = new PhoneFeatureRepository();
        return repository.GetFeaturesById(id);
    }        
}

ここに私のAPIルーティングがあります:

        config.Routes.MapHttpRoute(
            name: "ApiWithId", 
            routeTemplate: "Api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: new { id = @"^[0-9]+$" });

        config.Routes.MapHttpRoute(
            name: "ApiWithAction", 
            routeTemplate: "api/{controller}/{action}/{name}",
            defaults: null,
            constraints: new { name = @"^[a-z]+$" });

        config.Routes.MapHttpRoute(
            name: "ApiByAction",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { action = "Get" },
            constraints: new { id = @"^[0-9]+$" });

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

私はこのようにそれをテストしました:

/api/PhoneFeatures//api/PhoneFeatures/GetFeatureById/101

/api/PhoneFeatures/GetByFeatureId/12

あらゆる状況でスムーズに動作します:)

于 2014-03-04T03:00:57.830 に答える
0

呼び出し中に HttpGet を実行していることを願っていますGetFilteredCeremonies(Search filter)

その場合、渡しているような GET リクエストで複雑なオブジェクトを渡すことはできませんSearch

何らかの理由で、確実に get リクエストで複合型を取得したい場合は、いくつかの回避策があります。カスタム モデル バインダーを記述してから、属性を設定する必要がある場合があります。この記事を参照してください。

于 2014-03-04T05:21:06.897 に答える
0

名前が異なり、パラメーターが同じ 2 つのメソッドがあることを確認してください。

その場合は、いずれかのメソッドを削除して試してください。

このエラーは、同じパラメーターを探している 2 つのメソッドがあるために発生しました。それらのいずれかを削除してみてください...

于 2013-07-10T18:17:47.790 に答える