我正在开发一个带有Web Api 2的ASP.NET MVC网站,C#和.NET Framework 4.5.1。
我试图进行版本控制,但我做错了。
我在新命名空间中创建了一个新版本的控制器:
namespace MyProject.Web.API.Controllers.v2
{
[AllowAnonymous]
[ActionLogFilter]
public class ExternalCodesController : ApiController
{
public ExternalCodesController()
{
}
[HttpGet]
[Route("api/v2/ExternalCodes")]
public HttpResponseMessage Get()
{
[ ... ]
}
[HttpGet]
[Route("api/v2/ExternalCodes")]
public HttpResponseMessage Get(
byte? codeLevel,
int batchId,
int? lineId,
int productId,
string startingCode,
int? quantity)
{
[ ... ]
}
}
}
但是,当我使用此URI进行GET时:http://myHost:53827/api/v2/ExternalCodes?codeLevel=&batchId=5&lineId=&productId=7&startingCode=&quantity=
我得到一个NotFound
HTTP状态代码。但我也测试了这个URI:http://myHost:53827/api/v2/ExternalCodes
具有相同的状态代码。
我做错了什么?
我的WebApiConfig.cs
是:
namespace MyProject.Web.API
{
/// <summary>
/// Class to config Web API routes and filters.
/// </summary>
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Json configuration
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
// Remove formatting to make json smaller.
json.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.None;
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Filters.
config.Filters.Add(new ExceptionFilter());
config.Filters.Add(new UnhandledExceptionFilter());
}
}
}
答案 0 :(得分:1)
这实际上发生在我之前。这是因为在根控件中有两个同名的控制器&#39;控制器&#39;文件夹,不管子目录和命名空间(这种行为在内部区域不同)。尝试将控制器重命名为:
ExternalCodesV1Controller
和
ExternalCodesV2Controller
您应该能够保持名称空间甚至属性路由相同。
答案 1 :(得分:0)
一个讨厌的解决方案供您参考。我们的想法是将默认控制器选择器更改为自定义控制器选择器。
文件'ValuesController.cs':
namespace WebApplication4.Controllers
{
public class ValuesController : ApiController
{
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
}
文件'ValuesV2Controller.cs':
namespace WebApplication4.Controllers.V2
{
public class ValuesController : ApiController
{
public IEnumerable<string> Get()
{
return new string[] { "value3", "value4" };
}
}
}
创建自定义控制器选择器:
public class MyHttpControllerSelector : DefaultHttpControllerSelector
{
private HttpConfiguration _config;
public MyHttpControllerSelector(HttpConfiguration configuration) : base(configuration)
{
_config = configuration;
}
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
var routeData = request.GetRouteData();
var routeTemplate = routeData.Route.RouteTemplate;
if (routeTemplate.IndexOf("v2/values") != -1)
{
return new HttpControllerDescriptor(
_config, "Values",
typeof(WebApplication4.Controllers.V2.ValuesController));
} else if (routeTemplate.IndexOf("values") != -1)
{
return new HttpControllerDescriptor(
_config, "Values",
typeof(WebApplication4.Controllers.ValuesController));
}
return base.SelectController(request);
}
}
在“WebApiConfig.cs”文件中注册自定义控制器选择器:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "route1",
routeTemplate: "values"
);
config.Routes.MapHttpRoute(
name: "route2",
routeTemplate: "v2/values");
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Services.Replace(
typeof(IHttpControllerSelector),
new MyHttpControllerSelector(config));
}
}
因此,当您使用“http://localhost:13839/values”之类的网址时,您会获得value1和value2。对于网址“http://localhost:13839/v2/values”,值为3和value4。