8

名前とIDでデータをクエリする2つの異なるGETアクションが必要です。

私はこれらのルートを持っています:

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

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

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

およびコントローラーでのこれらのアクション:

    [HttpGet]
    public CompanyModel CompanyId(Guid id)
    {
          //Do something
    }


    [HttpGet]
    public CompanyModel CompanyName(string name)
    {
            //Do something
    }

次のような呼び出しhttp://localhost:51119/api/companies/CompanyId/3cd97fbc-524e-47cd-836c-d709e94c5e1e が機能し、「CompanyId」メソッドに到達している間、

同様の呼び出しでhttp://localhost:51119/api/companies/CompanyName/something404 が見つかりません

しかし、これ: ' http://localhost:51119/api/companies/CompanyName/?name=something' は正常に動作します

誰でもこの動作を説明できますか?私は何が間違っていますか?

4

1 に答える 1

10

Web API ルート セレクターには、URL の末尾にある文字列が GUID であるかどうかを知る方法がありません。したがって、適切な GET アクションの正しいルートを選択しようとしているわけではありません。

正しいルートを選択するには、GUID uri テンプレートのルート制約を追加する必要があります。

    public class GuidConstraint : IHttpRouteConstraint
    {
        public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values,
                          HttpRouteDirection routeDirection)
        {
            if (values.ContainsKey(parameterName))
            {
                string stringValue = values[parameterName] as string;

                if (!string.IsNullOrEmpty(stringValue))
                {
                    Guid guidValue;

                    return Guid.TryParse(stringValue, out guidValue) && (guidValue != Guid.Empty);
                }
            }

            return false;
        }
    }

次に、GUID を処理するルートに制約を追加します。

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

このルートは一般的な「文字列」ルートよりも具体的であるため、名前を解決するルートの上に配置する必要があります。

これは、アクションに適切にルーティングする必要があります。

お役に立てれば。

于 2013-03-28T12:13:53.743 に答える