我一直在使用WebApi,而我正试图了解使用路由属性与使用WebApi的差异如何根据函数名称自动创建路由。我有很多这种形式的控制器:
public class MyController : RestControllerBase
{
public async Task<HttpResponseMessage> GetData()
{
return _data;
}
[Route(ApiVersion.Version + "/MyController/{param}/specific/route")]
public async Task<HttpResponseMessage> GetMoreData()
{
return _moreData;
}
}
此控制器和其他所有控制器都指定了一个路由注册表:
routingManager.RegisterVersionedHttpRoute(
routeName: "MyController",
routeTemplate: "MyController/{param}",
defaults: new { controller = "MyController", param = RouteParameter.Optional },
version: ApiVersion.Version);
当我构建并测试我的API时,两个端点都可以正确访问。
我还使用基于名称空间的HttpControllerSelector进行覆盖(用于版本控制)。
我的问题是,除了传统的特定http路由调用功能之外,这两条路由的行为也不同。例如,在我重写的控制器选择器中,我必须编写此逻辑,以便控制器和路由正确映射:
private string GetControllerName(IHttpRouteData routeData)
{
if (routeData.GetSubRoutes() != null)
{
// With route attribute
var subroute = routeData.GetSubRoutes().FirstOrDefault();
var dataTokenValue = subroute.Route.DataTokens["actions"];
if (dataTokenValue == null) return null;
var controllername = ((HttpActionDescriptor[])dataTokenValue).First().ControllerDescriptor.ControllerName.Replace("Controller", string.Empty);
return controllername;
}
else
{
// Try Strategy for without route attribute.
return (String)routeData.Values["controller"];
}
}
private string GetVersion(IHttpRouteData routeData)
{
var routeTemplate = "";
if (routeData.GetSubRoutes() != null)
{
var subRouteData = routeData.GetSubRoutes().FirstOrDefault();
if (subRouteData == null) return null;
routeTemplate = subRouteData.Route.RouteTemplate;
}
else
{
routeTemplate = routeData.Route.RouteTemplate;
}
var index = routeTemplate.IndexOf("/");
if (index == -1)
{
return Unversioned;
}
var version = routeTemplate.Substring(0, index).ToUpperInvariant();
return version;
}
似乎具有explicit属性的路由将具有route.GetSubroutes()可用,而隐式路由不会。 这使我编写两种不同的方法来从传入请求中提取版本和控制器名称,然后才能正确路由它们。我可以忍受这一点,但WebApi内部的东西在路线之间创造了这种区别,这让我感到困扰。
不幸的是,我开始使用https://github.com/domaindrivendev/Swashbuckle来记录我的api并遇到了类似的问题。 swagger页面为具有Route属性的路由正确生成,但完全忽略隐式路由。我怀疑导致此问题的问题与我选择逻辑中的分支相同。
我已经在网上找到了尽可能多的ApiExplorer,WebAPI和其他文档,但我还没有找到解决方案来使隐式/显式路由方法同质化。它甚至可能是实施中的一个错误。
我应该从哪里离开?
答案 0 :(得分:0)
所以这里的答案是Web Api 2存在错误或不一致 要进行验证,您可以运行此代码段。在我提到的情况下,ApiExplorer不会返回未明确标记路径属性的路径的结果。
IApiExplorer apiExplorer = configuration.Services.GetApiExplorer();
foreach (ApiDescription api in apiExplorer.ApiDescriptions)
{
Console.WriteLine("Uri path: {0}", api.RelativePath);
Console.WriteLine("HTTP method: {0}", api.HttpMethod);
foreach (ApiParameterDescription parameter in api.ParameterDescriptions)
{
Console.WriteLine("Parameter: {0} - {1}", parameter.Name, parameter.Source);
}
Console.WriteLine();
}