gpt4 book ai didi

c# - ASP.net Web Api 版本控制

转载 作者:行者123 更新时间:2023-12-03 19:29:05 25 4
gpt4 key购买 nike

我有 ASP.net Web Api 项目,我决定是时候支持版本控制了。我正在使用官方 Microsoft Nuget 来支持版本控制(更多信息 here ),我决定按 namespace 进行版本控制(例如 here )。

不幸的是,我无法让代码工作。如果我这样调用我的方法:

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);
}

保存的 Controller (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;
}

}
}

保存的 Controller (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/已保存

这些都不符合您的预期路线:

http://localhost:7291/api/Saved/GetNumberOfSavedWorkoutsForUserhttp://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.0http://localhost:7291/api/Saved/GetNumberOfSavedWorkoutsForUser?api-version=2.0

希望对你有帮助

关于c# - ASP.net Web Api 版本控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46177972/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com