API 控制器可以工作,但 Web 剃须刀控制器不能与 owin 一起使用



我对此感到疯狂。

我正在用Visual Studio 2012 Premium、.NET Framework 4.5.1和C#开发一个ASP.NET Web Api 2.2项目。

我创建了一个空的ASP.NET MVC 5项目。我已经删除了Global.asax并创建了这个Startup.cs类:

using Microsoft.Owin;
using Ninject;
using Ninject.Web.Common.OwinHost;
using Ninject.Web.WebApi.OwinHost;
using Owin;
using System.Reflection;
using System.Web.Http;
using System.Web.Routing;
using MyProject.Web.API.App_Start;
[assembly: OwinStartup(typeof(MyProject.Web.API.Startup))]
namespace MyProject.Web.API
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            var webApiConfiguration = new HttpConfiguration();
            webApiConfiguration.Routes.MapHttpRoute(
                name: "Default",
                routeTemplate: "{controller}/{id}",
                defaults: new { id = RouteParameter.Optional });
            webApiConfiguration.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
            webApiConfiguration.Routes.MapHttpRoute(
                name: "ProductionOrderActionApi",
                routeTemplate: "api/MyProductionOrders/{orderNumber}/{action}",
                defaults: new { controller = "MyProductionOrders" });
            app.UseNinjectMiddleware(CreateKernel);
            app.UseNinjectWebApi(webApiConfiguration);
        }
        private static StandardKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());
            RegisterServices(kernel);
            return kernel;
        }
        private static void RegisterServices(IKernel kernel)
        {
            var containerConfigurator = new NinjectConfigurator();
            containerConfigurator.Configure(kernel);
        }
    }
}

该项目可以很好地使用ApiController类,但当我尝试访问控制器时,我会得到HTTP 404状态代码:未找到。

我必须做些什么才能允许使用网页?我认为问题出在Routes上,但我曾尝试将RouteConfig添加到该项目中,但我不知道如何添加。

我在谷歌上搜索了很多,但没有找到任何与我的问题有关的内容(或者可能我没有输入正确的搜索词)。

如果你需要NinjectConfigurator类,请告诉我,我会添加它。

您需要使用控制器的MapRoute。

 routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }

MapRoute是一个扩展方法,其中MvcRouteHandler被设置为请求的路由处理程序。如果您还没有映射一个要由MvcRouteHandler处理的给定路由,那么您就没有参与导致控制器实例化的Mvc请求处理管道。

MapRoute使用MvcRouteHandler

   public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)
    {
      if (routes == null)
        throw new ArgumentNullException("routes");
      if (url == null)
        throw new ArgumentNullException("url");
      Route route = new Route(url, (IRouteHandler) new MvcRouteHandler())
      {
        Defaults = RouteCollectionExtensions.CreateRouteValueDictionaryUncached(defaults),
        Constraints = RouteCollectionExtensions.CreateRouteValueDictionaryUncached(constraints),
        DataTokens = new RouteValueDictionary()
      };
      ConstraintValidation.Validate(route);
      if (namespaces != null && namespaces.Length > 0)
        route.DataTokens["Namespaces"] = (object) namespaces;
      routes.Add(name, (RouteBase) route);
      return route;
    }

MapHttpRoute使用HttpMessageHandler:

public static IHttpRoute MapHttpRoute(this HttpRouteCollection routes, string name, string routeTemplate, object defaults, object constraints, HttpMessageHandler handler)
{
  if (routes == null)
    throw Error.ArgumentNull("routes");
  HttpRouteValueDictionary routeValueDictionary1 = new HttpRouteValueDictionary(defaults);
  HttpRouteValueDictionary routeValueDictionary2 = new HttpRouteValueDictionary(constraints);
  IHttpRoute route = routes.CreateRoute(routeTemplate, (IDictionary<string, object>) routeValueDictionary1, (IDictionary<string, object>) routeValueDictionary2, (IDictionary<string, object>) null, handler);
  routes.Add(name, route);
  return route;
}

在我看来,路由设置确实没有设置,因为您只为webapi定义了路由。mvc和webapi的路由配置有点不同,所以你不能像在那里那样为两者设置路由。引用我正在读的一本书:

避免框架之间冲突的关键是谨慎行事设置;为了方便,默认情况下,ASP.NET Web API将占用URI/api下的空格,而所有其他根级别的URL都将由MVC处理。Web API路由通常在针对HttpConfiguration对象的WebApiConfig静态类及其Route属性,而MVC路由是在静态RouteConfig中定义的类,直接针对System.Web.RouteCollection.

 //Web API routing configuration
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            // Web API routes
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
            );
        }
    }
    //MVC routing configuration
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }

最新更新