我无法使用 RouteAttribute 到达路线 api/v2/ExternalCodes

I can't reach route api/v2/ExternalCodes using RouteAttribute

我正在开发一个 ASP.NET MVC 网站,其中还包括 Web Api 2、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());
        }
    }
}

这在我以前确实发生过。这是因为在根 'Controllers' 文件夹中有两个同名的控制器,无论子目录和名称空间如何(此行为在区域内是不同的)。尝试将控制器重命名为:

ExternalCodesV1Controller

ExternalCodesV2Controller

您应该能够保持名称空间甚至属性路由相同。

一个令人讨厌的解决方案,供您参考。这个想法是将默认控制器选择器更改为您的自定义选择器。

文件'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));
        }
    }

因此,当您使用 url 时,例如“http://localhost:13839/values', you get value1 and value2. And value3 and value4 for url 'http://localhost:13839/v2/values”。