Api 控制器可以工作,但网络剃须刀控制器不能使用 owin

Api controllers work but web razor controllers don't with 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 class:

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 classes, but when I try to access to a Controller 下运行良好,我收到 HTTP 404 状态代码:未找到。

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

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

如有需要NinjectConfiguratorclass请告诉我,我加

在我看来,路由设置确实没有设置,因为您只定义了 webapi 的路由。 mvc 和 webapi 的路由配置略有不同,因此您不能像在此处那样为两者设置路由。 摘自我正在阅读的书:

The key to avoiding conflict between the frameworks is a careful route setup; to facilitate that, by default ASP.NET Web API will occupy URI space under /api, while all of the other root-level URLs will be handled by MVC. Typically Web API routes are defined in the WebApiConfig static class against the HttpConfiguration object and its Route property, while MVC routes are defined in the static RouteConfig class, directly against the 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 }
            );
        }
    }

您需要为控制器使用 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;
}