簡體   English   中英

ASP.net Web Api版本控制

[英]ASP.net Web Api Versioning

我有ASP.net Web Api項目,我認為是時候支持版本控制了。 我正在使用官方的Microsoft Nuget來支持版本控制( 這里有更多信息),我決定使用命名空間版本(例如這里 )。

不幸的是我無法獲得代碼。 如果我這樣調用我的方法:

http://localhost:7291/api/Saved/GetNumberOfSavedWorkoutsForUser?api-version=2.0

我收到錯誤:

Multiple types were found that match the controller named 'Saved'. This can happen if the route that services this request ('api/{controller}/{action}/{id}') found multiple controllers defined with the same name but differing namespaces, which is not supported.

如果我這樣稱呼它: http://localhost:7291/v2/Saved/GetNumberOfSavedWorkoutsForUser

我收到錯誤404:

The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

我不確定我做錯了什么。 這是我的代碼:

Startup.cs

public void Configuration(IAppBuilder app)
    {
        var configuration = new HttpConfiguration();
        var httpServer = new HttpServer(configuration);


        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

        // reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
        configuration.AddApiVersioning(o => 
        {
            o.AssumeDefaultVersionWhenUnspecified = true;
            o.ReportApiVersions = true; 
            o.DefaultApiVersion = ApiVersion.Default;
        });


        configuration.Routes.MapHttpRoute(
            "VersionedUrl",
            "v{apiVersion}/{controller}/{action}/{id}",
            defaults: null,
            constraints: new { apiVersion = new ApiVersionRouteConstraint() });

        configuration.Routes.MapHttpRoute(
            "VersionedQueryString",
            "api/{controller}/{action}/{id}",
            defaults: null);


        app.UseWebApi(httpServer);

        ConfigureAuth(app);
    }

保存的控制器(v1)

namespace Master.Infrastructure.Api.Controllers
{

    [Authorize]
    [RoutePrefix("api/Saved")]
    [ApiVersion("1.0")]
    public class SavedController : ApiController
    {

        private readonly IUserService _userService;

        public SavedController(IUserService userService)
        {
            _userService = userService;

        }


        [HttpGet]
        [ActionName("GetNumberOfSavedWorkouts")]
        public async Task<NumberOfSavedWorkouts> GetNumberOfSavedWorkouts()
        {
            var numOfSavedWorkouts = new NumberOfSavedWorkouts
            {
                CurrentNumberOfSavedWorkouts =
                    await _userService.GetNumberOfSavedWorkoutsForUserAsync(User.Identity.GetUserId())
            };

            return numOfSavedWorkouts;
        }

    }
}

保存的控制器(v2)

namespace Master.Infrastructure.Api.V2.Controllers
{
    [Authorize]
    [ApiVersion("2.0")]
    [RoutePrefix("v{version:apiVersion}/Saved")]
    public class SavedController : ApiController
    {

        private readonly ISavedWorkoutService _savedWorkoutService;


        public SavedController(ISavedWorkoutService savedWorkoutService)
        {       
            _savedWorkoutService = savedWorkoutService;
        }


        [ActionName("GetNumberOfSavedWorkoutsForUser")]
        public async Task<IHttpActionResult> GetNumberOfSavedWorkoutsForUser()
        {
            var cnt = await _savedWorkoutService.CountNumberOfSavedWorkoutsForUser(User.Identity.GetUserId());

            return Ok(cnt);
        }
    }
}

你的路線不正確。 除非你真的需要,否則我強烈建議你不要混淆路由樣式。 排除故障可能非常困難。

這里有幾件事:

  1. 您有通過查詢字符串和URL段進行版本配置,您想要哪一個? 我會選擇一個。 默認和我的建議是使用查詢字符串方法。
  2. 您的基於約定的路由與基於屬性的路由不同
  3. 由於您已定義RoutePrefixAttribute ,因此您似乎更喜歡屬性路由樣式。 我將刪除所有基於約定的路由(例如: configuration.Routes.MapHttpRoute )。

在您的約定中,路由模板:

v{apiVersion}/{controller}/{action}/{id}

但在你的屬性中它是:

api/Saved

這些都不符合您的預期路線:

http://localhost:7291/api/Saved/GetNumberOfSavedWorkoutsForUser http://localhost:7291/v2/Saved/GetNumberOfSavedWorkoutsForUser

對於使用路由屬性的查詢字符串方法,事情應如下所示:

configuration.AddApiVersioning(o => o.ReportApiVersions = true);

namespace Master.Infrastructure.Api.Controllers
{
    [Authorize]
    [ApiVersion("1.0")]
    [RoutePrefix("api/Saved")]
    public class SavedController : ApiController
    {
       private readonly IUserService _userService;
       public SavedController(IUserService userService) => _userService = userService;

       [HttpGet]
       [Route("GetNumberOfSavedWorkouts")]
       public async Task<IHttpActionResult> GetNumberOfSavedWorkouts()
       {
            var userId = User.Identity.GetUserId();
            var count = await _userService.GetNumberOfSavedWorkoutsForUserAsync(userId);
            return Ok(new NumberOfSavedWorkouts(){ CurrentNumberOfSavedWorkouts = count });
       }
    }
}

namespace Master.Infrastructure.Api.V2.Controllers
{
    [Authorize]
    [ApiVersion("2.0")]
    [RoutePrefix("api/Saved")]
    public class SavedController : ApiController
    {
       private readonly ISavedWorkoutService _savedWorkoutService;
       public SavedController(ISavedWorkoutService savedWorkoutService) => _savedWorkoutService = savedWorkoutService;

       [HttpGet]
       [Route("GetNumberOfSavedWorkoutsForUser")]
       public async Task<IHttpActionResult> GetNumberOfSavedWorkoutsForUser()
       {
            var userId = User.Identity.GetUserId();
            var count = await _savedWorkoutService.CountNumberOfSavedWorkoutsForUser(userId);
            return Ok(count);
       }
    }
}

然后應該有以下工作:

http://localhost:7291/api/Saved/GetNumberOfSavedWorkouts?api-version=1.0 http://localhost:7291/api/Saved/GetNumberOfSavedWorkoutsForUser?api-version=2.0

我希望有幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM