【发布时间】:2016-01-11 06:46:42
【问题描述】:
我正在尝试使用header 来api versioning,但在different folder structure 中,如下所示。
在Controller folder 中有V1 子文件夹在CustomerController.cs
和
在Controller folder 中有V2 子文件夹在CustomerController.cs 内
当我使用上面的URL 使用 api 版本时工作正常。
我的问题是当我使用header 尝试这种方法时,它给了我以下错误:
{ "Message": "发生错误。", "ExceptionMessage": “找到了与名为‘客户’的控制器匹配的多种类型。 如果服务此请求的路由会发生这种情况 ('api/{controller}/{id}') 找到了多个使用 名称相同但命名空间不同,这是不受支持的。\r\n\r\n 对“客户”的请求已找到以下匹配项 控制器:\r\nApiVersion.Controllers.V1.CustomerController\r\nApiVersion.Controllers.V2.CustomerController","ExceptionType":"System.InvalidOperationException","StackTrace":" 在 System.Web.Http.Dispatcher.DefaultHttpControllerSelector.SelectController(HttpRequestMessage 请求)\r\n 在 System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()" }
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
CustomeControllerSelector.cs
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
var controllers = GetControllerMapping();
var routeData = request.GetRouteData();
var controllerName = routeData.Values["controller"].ToString();
//HttpControllerDescriptor controllerDescriptor;
var version = GetVersionFromAcceptHeaderVersion(request);
var controllerKey = String.Format(CultureInfo.InvariantCulture, "{0}.{1}",
version, controllerName);
//if (controllers.TryGetValue(controllerName, out controllerDescriptor))
// {
if (!string.IsNullOrEmpty(version))
{
HttpControllerDescriptor versionedControllerDescriptor;
if (controllers.TryGetValue(controllerKey, out versionedControllerDescriptor))
{
return versionedControllerDescriptor;
}
}
return null;
}
private string GetVersionFromAcceptHeaderVersion(HttpRequestMessage request)
{
var acceptHeader = request.Headers.Accept;
foreach (var mime in acceptHeader)
{
if (mime.MediaType == "application/json" || mime.MediaType == "text/html")
{
var version = mime.Parameters
.Where(v => v.Name.Equals("version", StringComparison.OrdinalIgnoreCase))
.FirstOrDefault();
if (version != null)
{
return version.Value;
}
return string.Empty;
}
}
return string.Empty;
}
【问题讨论】:
标签: c# asp.net asp.net-web-api asp.net-web-api2 asp.net-web-api-routing