web-dev-qa-db-ja.com

Web API2エリアルート

Asp.net mvc5とwebapi2を使用しています。asp.netmvc5プロジェクトでは、すべてが機能しています...しかし、新しい領域を使用しているときに、web api2ルートを追加しようとしています。

プロジェクトルートでWebAPI2コントローラーが機能しています。

 //this is working 
   namespace EtracsWeb.Controllers
    {
        public class TestController : ApiController
        {
            //localhost:port/api/test ...this is working
            [HttpGet]
            public HttpResponseMessage Get()
            {

                return new HttpResponseMessage()
                {
                    Content = new StringContent("GET: Test message")
                };
            }

        }
    }

したがって、Global.asaxrouteconfig.cs、およびwebapiconfig.csは正しいと想定しています...(表示されていません)...

しかし今、私は自分のAREASでWeb API2を機能させようとしています...

私はウェブ上で見つけることができるすべてを読みました、そしてこれはそれがうまくいくはずのようです:

namespace EtracsWeb.Areas.WorkOrder
{
    public class WorkOrderAreaRegistration : AreaRegistration
    {
        public override string AreaName
        {
            get
            {
                return "WorkOrder";
            }
        }

        public override void RegisterArea(AreaRegistrationContext context)
        {

            context.Routes.MapHttpRoute(
                    name: "AuditModel_Api",
                    routeTemplate: "WorkOrder/api/AuditModelApi/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );

        //default
            context.Routes.MapHttpRoute(
                    name: "WorkOrder_Api",
                    routeTemplate: "WorkOrder/api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );

            context.MapRoute(
                 "WorkOrder_default",
                "WorkOrder/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

私のコントローラーコードは次のとおりです。

namespace EtracsWeb.Areas.WorkOrder.ApiControllers
{
    public class AuditModelApiController : ApiController
    {
        IManufacturerStopOrderModelService auditModelService = new WorkOrder.Services.VWAuditModelService(UserSession.EtracsUserID, UserSession.ProgramID, UserSession.EtracsSessionID, UserSession.ConnectionString);

        [HttpGet]
        [Route("AuditModelApi")]
        public HttpResponseMessage Get()
        {

            return new HttpResponseMessage()
            {
                Content = new StringContent("GET: Test message")
            };
        }

        [Route("AuditModelApi/AuditModels")]
        public IEnumerable<VwAuditModel1> GetAuditModels()
        {
                return auditModelService.GetModels();
        }

        public IHttpActionResult UpdateAuditMode()
        {
            //example of what can be returned ... NotFound, Ok ... look into uses...

            VwAuditModel1 result = new VwAuditModel1();
            return Ok(result);

            return NotFound();
        }
    }
}

[Route]...という名前の属性がある場合とない場合のコントローラーを試しましたが、どちらも動作しません...

両方の単純なケース

    public HttpResponseMessage Get()

そして「本当の」ケース

  public IEnumerable<VwAuditModel1> GetAuditModels()

同じ結果を返します。ブラウザから、

http://localhost:64167/WorkOrder/api/AuditModelApi

そして

http://localhost:64167/WorkOrder/api/AuditModelApi/AuditModels

私は次のようになります:

<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://localhost:64167/WorkOrder/api/AuditModelApi/AuditModels'.
</Message>
<MessageDetail>
No route providing a controller name was found to match request URI 'http://localhost:64167/WorkOrder/api/AuditModelApi/AuditModels'
</MessageDetail>
</Error>
13
user2040850

HttpConfigurationオブジェクトからGlobalConfigurationインスタンスを取得し、_AreaRegistration.cs_のMapHttpAttributeRoutes()メソッド内からRegisterArea()メソッドを呼び出す必要があります。 。

_    public override void RegisterArea(AreaRegistrationContext context) 
    {
        GlobalConfiguration.Configuration.MapHttpAttributeRoutes();

        //... omitted code  
    }
_

最後に、WebApiConfig remove config.MapHttpAttributes()メソッドを使用する必要があります。そうしないと、重複した例外が発生します。

_public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.EnableCors();

        // Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));


        // Web API routes
        //config.MapHttpAttributeRoutes();

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

まず、ルートをそれが属するエリアに登録する必要があります。これは意味があります。したがって、AreaNameAreaRegistrationクラス内に必ずusing System.Web.Httpを追加して、拡張メソッドMapHttpRouteを取得してください。 、それはSystem.Web.Mvcの一部ではありません。

上記の順序は少しずれているため、404が発生しています。次のルートを追加します。

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

気を付けて、プロパティAreaNameからエリア名を追加したい場合(もちろん、優れたコーディング方法に関心があります;)):

context.Routes.MapHttpRoute(
            name: "AreaNameWebApi",
            routeTemplate: string.Concat("api/", AreaName, "/{controller}/{id}"),
            defaults: new { id = RouteParameter.Optional }
        );

これにより、404の問題が修正されます。 Web APIモジュールでは、デフォルトで最初に「api」をスキャンしてコントローラーを探す場所を決定します(そうしないと、混乱します。魔法ではありません)。したがって、エリア名とコントローラーを動的に追加するときは、最初にapiを使用する必要があります。もちろん、ルートをハードコーディングすることでこの順序を変更できますが、ルート構成ですべてのルートとすべてのコントローラーを指定するか、RouteAttributeを使用する必要があるため、お勧めしません。

さらに、最初に「api」を使用すると、APIをあちこちに配置する代わりに、あなたとあなたのユーザーにとって見栄えの良い標準のURLになります。ここにいくつかのサンプルがあります:

http://site/api/members/myAccount/update
http://site/api/members/myAccount/get/12345
http://site/api/members/contacts/getByOwnerId/12345

お役に立てれば!

ゼブ

5
Zev Butler

その特定のAPI呼び出しの問題は、ルートで使用するコントローラーを指定していないことです。

        context.Routes.MapHttpRoute(
                name: "AuditModel_Api",
                routeTemplate: "WorkOrder/api/AuditModelApi/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

する必要があります

        context.Routes.MapHttpRoute(
                name: "AuditModel_Api",
                routeTemplate: "WorkOrder/api/AuditModelApi/{id}",
                defaults: new { controller = "AuditModelApi", id = RouteParameter.Optional }
            );

URLの定数セグメントは、一致するURLを指定するためのものですが、コントローラーとアクションに到達するためには、ルート値を指定する必要があります。 {controller}セグメントにしない限り、コントローラー名として使用するセグメントを知る方法はありません。

3
NightOwl888