Shi*_*nga 12 c# asp.net asp.net-web-api asp.net-core
在前面asp.net web api,我实现DefaultHttpControllerSelector指定我希望请求如何定位我的控制器.我经常使用不同名称的不同控制器,但用于相同的过程.唯一的区别是一个版本的版本高于另一个版本.
例如,我可以有一个名为的控制器BookingV1Controller,用于处理服务的第一个版本.我也有BookingV2Controller,它旨在处理服务的第二版.然后,客户端应用程序将使用此URL向服务发出请求http://myservice.com/api/v2/booking/someaction?id=12.为了处理请求,我将提供一个自定义实现,DefaultHttpControllerSelector以根据请求的版本选择所需的控制器的相应版本.
但是,我似乎没有办法做到这一点ASP.NET Core.我到处搜索都无济于事.没有可以帮助的文档.
如果有人能在这里帮助我,我将不胜感激.谢谢.
更新
我还想知道如果在自定义标头中指定版本该怎么办.例如X-Version:v1
更新2
要求是不应在URL中公开服务的版本.如果没有版本,则服务返回有关如何添加版本的说明.如果请求的版本中没有请求的控制器,系统将搜索较低版本.如果它在任何较低版本中找到它,它就会使用它.这样做的原因是为了防止在所有版本上重复使用控制器.但是使用ASP.NET Core,这可能是不可能的.
Min*_*ata 21
这是我偶然发现的一个非常古老的问题,但现在有更好的解决方案.有这个包
Microsoft.AspNetCore.Mvc.Versioning
其中有一个功能更丰富的实现版本控制的方法.这些包括能够使用URL查询字符串,URL路径,标题或自定义版本阅读器.能够从HTTPContext等读取版本
简而言之,您将以下内容添加到startup.cs中的ConfigureServices方法中
services.AddApiVersioning(o => {
o.ReportApiVersions = true;
o.AssumeDefaultVersionWhenUnspecified = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
});
Run Code Online (Sandbox Code Playgroud)
然后你必须用ApiVersion装饰你的控制器.
[ApiVersion("1.0")]
[Route("api/home")]
public class HomeV1Controller : Controller
{
[HttpGet]
public string Get() => "Version 1";
}
[ApiVersion("2.0")]
[Route("api/home")]
public class HomeV2Controller : Controller
{
[HttpGet]
public string Get() => "Version 2";
}
Run Code Online (Sandbox Code Playgroud)
您也可以通过将其放入路径中来实现它.
[ApiVersion("1.0")]
[Route("api/{version:apiVersion}/home")]
public class HomeV1Controller : Controller
{
[HttpGet]
public string Get() => "Version 1";
}
[ApiVersion("2.0")]
[Route("api/{version:apiVersion}/home")]
public class HomeV2Controller : Controller
{
[HttpGet]
public string Get() => "Version 2";
}
Run Code Online (Sandbox Code Playgroud)
当你实际上通过Microsoft软件包实现它的这种方法时,它也意味着你可以弃用版本,拥有版本发现,轻松地从HttpContext访问版本号等等.如果它是你真的可以做的只是在你的路线硬编码.
有关详细信息(包括在标题中使用它):
http://dotnetcoretutorials.com/2017/01/17/api-versioning-asp-net-core/
http://www.hanselman.com/blog/ASPNETCoreRESTfulWebAPIVersioningMadeEasy.aspx
Pet*_*ino 11
在为这个问题敲了几天之后,我正是为此目的创建了一个软件包.它不需要属性.
https://github.com/GoAheadTours/NamespaceVersioning
总之,您可以在启动文件中注册IApplicationModelConvention,它可以迭代控制器并根据命名空间注册路由.我创建了一个v1文件夹,并将我的控制器放入其中
实现IApplicationModelConvention的类实现了一个带有ApplicationModel参数的Apply方法,该参数可以访问应用程序中的控制器及其现有路由.如果我看到控制器没有在我的类中设置路由,我从命名空间获取版本并使用预定义的URL前缀为该版本生成路由.
public void Apply(ApplicationModel application) {
foreach (var controller in application.Controllers) {
var hasRouteAttribute = controller.Selectors.Any(x => x.AttributeRouteModel != null);
if (hasRouteAttribute) {
continue;
}
var nameSpace = controller.ControllerType.Namespace.Split('.');
var version = nameSpace.FirstOrDefault(x => Regex.IsMatch(x, @"[v][\d*]"));
if (string.IsNullOrEmpty(version)) {
continue;
}
controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel() {
Template = string.Format(urlTemplate, apiPrefix, version, controller.ControllerName)
};
}
}
Run Code Online (Sandbox Code Playgroud)
我在github上有所有代码,并且还有一个指向nuget上的包的链接
使用路由属性来控制版本.
即
[Route("api/v1/[controller]")]
public class BookingV1Controller : Controller
{
....
}
[Route("api/v2/[controller]")]
public class BookingV2Controller : Controller
{
....
}
Run Code Online (Sandbox Code Playgroud)
有关从标准Web Api和.NET Core ASP.NET迁移的更多信息,请参阅:MSDN:从ASP.NET Web Api迁移
| 归档时间: |
|
| 查看次数: |
9636 次 |
| 最近记录: |