如何使ASP.NET Web API与版本控制和帮助页面扩展一起使用?
我已经在我的WebAPI应用程序中实现了一个版本控制框架,并且非常希望能够使用Microsoft的新帮助页面扩展。
Microsoft.AspNet.WebApi.HelpPage
SDammann.WebApi.Versioning
很简单,我不知道如何让他们两个一起工作。 我有2个项目:
- AdventureWorks.Api(主要主机/根应用程序)
- AdventureWorks.Api.v1(包含API的第一个版本的类库)
版本控制按预期工作。
我已经尝试在根应用程序上安装HelpPage包,当我浏览到帮助页面时,似乎没有找到任何控制器。 在内部我相信它使用:
Configuration.Services.GetApiExplorer().ApiDescriptions
这不会返回任何结果,因此我收到错误。
任何人都可以协助我让这两个包一起工作吗?
编辑:在开始时,我不确定这是一个路由问题,但最近的评论似乎暗示。 这是我的RouteConfig.cs
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapHttpRoute( name: "SldExportAliasApi", routeTemplate: "api/v{version}/sld-export/{id}", defaults: new { id = RouteParameter.Optional, controller = "Export" } ); routes.MapHttpRoute( name: "LinkRoute", routeTemplate: "api/v{version}/link/{system}/{deployment}/{view}", defaults: new { controller = "Link" } ); routes.MapHttpRoute( name: "DefaultSubParameterApi", routeTemplate: "api/v{version}/{controller}/{id}/{param}", defaults: new { id = RouteParameter.Optional, param = RouteParameter.Optional } ); routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/v{version}/{controller}/{action}/{id}", defaults: new { action = "Index", id = RouteParameter.Optional } ); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }
您需要从项目AdventureWorks.Api.v1项目中获取文档XML文件,并将其放在AdventureWorks.Api项目的bin文件夹中:
然后将这些行添加到Application_Start方法:
// enable API versioning GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector), new RouteVersionControllerSelector(GlobalConfiguration.Configuration)); GlobalConfiguration.Configuration.Services.Replace(typeof(IApiExplorer), new VersionedApiExplorer(GlobalConfiguration.Configuration)); GlobalConfiguration.Configuration.Services.Replace(typeof(IDocumentationProvider), new XmlCommentDocumentationProvider(System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\Adventure.Api.v1.XML"));
然后,您可以使用文档查看API。
有时版本号无法正确拾取,并由???替换
要修复此添加:
if (api.ActionDescriptor.ControllerDescriptor.ControllerType.Namespace != null) { var versionName = api.ActionDescriptor.ControllerDescriptor.ControllerType.Namespace.Replace(".Controllers", "").Split('.').Last(); api.RelativePath = api.RelativePath.Replace("v???", versionName); }
准确到这个地方你的ApiGroup.cshtml:
@foreach (var api in Model) { if (api.ActionDescriptor.ControllerDescriptor.ControllerType.Namespace != null) { var versionName = api.ActionDescriptor.ControllerDescriptor.ControllerType.Namespace.Replace(".Controllers", "").Split('.').Last(); api.RelativePath = api.RelativePath.Replace("v???", versionName); } @api.HttpMethod.Method @api.RelativePath @if (api.Documentation != null) { @api.Documentation
} else { No documentation available.
} }
这应该做的伎俩!
我无法弄清楚如何评论一篇文章:(我认为这应该是这个问题的标记答案下的评论,但SDamman更新,我需要做的就是这个
// enable API versioning GlobalConfiguration.Configuration.Services.Replace(typeof(System.Web.Http.Dispatcher.IHttpControllerSelector), new SDammann.WebApi.Versioning.RouteVersionedControllerSelector(GlobalConfiguration.Configuration)); GlobalConfiguration.Configuration.Services.Replace(typeof(IApiExplorer), new SDammann.WebApi.Versioning.VersionedApiExplorer(GlobalConfiguration.Configuration));
有一种名为VersionedApiExplorer的类型,效果很好。 希望这有助于解决方案现在变得更加容易。
编辑:我在尝试获得自己的帮助后意识到我的回答并不明显。
要使帮助页面正常工作,您需要做的就是替换全局配置IApiExplorer,就是这样。 只需在根据sdammans指令更改处理程序后立即执行此操作。
我同意@mortware,如果你使用默认的Get()
/ Post()
方法,web api的默认路由将意味着你的url应该看起来像“site / api / controllerName /”。 如果您使用特定命名的方法,那么该路由看起来像“site / api / controllerName / methodName”。
我也遇到了参数名称的困难。 例如,如果您在/App_Start/WebApiConfig.cs中指定的路线中有;
// Controller with ID // To handle routes like `/api/VTRouting/1` config.Routes.MapHttpRoute( name: "ControllerAndId", routeTemplate: "api/{controller}/{id}", defaults: null, constraints: new { id = @"^\d+$" } // Only integers ); // Controllers with Actions // To handle routes like `/api/VTRouting/route` config.Routes.MapHttpRoute( name: "ControllerAndAction", routeTemplate: "api/{controller}/{action}/{id}", defaults: null, constraints: new { id = @"^\d+$" } // Only integers );
那么你的http动词的方法参数必须有一个名为“id”的参数,例如;
// url: site/api/controller/ public HttpResponseMessage Get(int id) { return null; /*dummy*/ } // url: site/api/controller/ public HttpResponseMessage Post(int id) { return null; /*dummy*/ } // url: site/api/controller/SomeAction/ public HttpResponseMessage SomeAction(int id) { return null; /*dummy*/ }
如果你有类似的东西;
public HttpResponseMessage Get(int myID) { return null; /*dummy*/ }
它不起作用,因为“myID”参数与路由中指定的{id}
不匹配。 正如@OakNinja指出的那样,我们需要您在WebApiConfig.cs中的路由来帮助您查明确切的原因
- 如何在ASP.NET MVC控制器中访问Request.cookies?
- 将XML解析列表从控制器传递到ASP.NET MVC中的视图
- 以编程方式在asp.net应用程序上的microsoft.identityModel中配置federatedAuthentication元素
- Html.Raw不能正常运行asp.net mvc
- 将entity framework从MVC移动到另一个项目会导致重新迁移
- 多重约束违反了entity framework5
- 从ViewModel获取属性
- 在ASP.Net Identity 2.0上包含属性UserManager.Users.ToListAsync和UserManager.FindByIdAsync
- Ajax.BeginForm导致重定向到部分视图而不是就地