【问题标题】:Get Controller-instances from Routes.MapHttpRoute从 Routes.MapHttpRoute 获取控制器实例
【发布时间】:2014-06-04 20:05:24
【问题描述】:

在我工作的现有 C# Web 项目中,我添加了一个 Web API 部分。

在我自己用于 Web API 的四个类中,我需要访问一些现有的控制器类。现在我只是为它们创建一个新实例,一切都按预期工作:ProductController controller = new ProductController();

不过,在应该已经存在的情况下创建一个新的 ProductController 显然不是一个好习惯。我知道控制器是在 Routes.MapHttpRoute 的配置文件中创建的,因为它使用 C# Web MVC 方法。下面我复制了那段代码:

config.Routes.MapHttpRoute(
    name: "Default",
    routeTemplate: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    namespaces: new[] { "MyProject.Controllers" }
);
route.DataTokens["UseNamespaceFallback"] = false;

我尝试在我的一个 API 类中访问这些控制器,如下所示:

private void getControllerInstance()
{
    var url = "~/Products";
    // Original path is stored and will be rewritten in the end
    var httpContext = new HttpContextWrapper(HttpContext.Current);
    string originalPath = httpContext.Request.Path;

    try
    {
        // Fake a request to the supplied URL into the routing system
        httpContext.RewritePath(url);
        RouteData urlRouteData = RouteTable.Routes.GetRouteData(httpContext);

        // If the route data was not found (e.g url leads to another site) then authorization is denied.
        // If you want to have a navigation to a different site, don't use AuthorizationMenu
        if (urlRouteData != null)
        {
            string controllerName = urlRouteData.Values["controller"].ToString();

            // Get an instance of the controller that would handle this route
            var requestContext = new RequestContext(httpContext, urlRouteData);
            var controllerFactory = ControllerBuilder.Current.GetControllerFactory();
            // TODO: Fix error (The controller for path '/Products' was not found or does not implement IController.) on this line:
            var controllerbase = (ControllerBase)controllerFactory.CreateController(requestContext, controllerName);
            controller = (ProductController)controllerbase;
        }
    }
    finally
    {
        // Reset our request path.
        httpContext.RewritePath(originalPath);
    }
}

您可能已经从 TODO 评论中注意到,在 var controllerbase = (ControllerBase)controllerFactory.CreateController(requestContext, controllerName); 行,我收到以下错误:

HttpException 被用户代码取消处理:路径“/Products”的控制器未找到或未实现 IController。

有谁知道如何解决这个错误?这与配置文件中以下两行代码之一有关吗?

namespaces: new[] { "MyProject.Controllers" }

route.DataTokens["UseNamespaceFallback"] = false;

还是我做错了什么?

【问题讨论】:

  • @chrfin 为什么要删除我的问题标题中的“C# Web”部分?我总是在问题前面添加编程语言,以便滚动查看 stackoverflow 问题的人可以更轻松地看到它是针对 C# 的。 (我知道这也可以在标签上看到,但如果它也在标题中不是更容易发现吗?)
  • 标签不应添加到标题中——这就是“准则”。如果有人(比如我)只想要 C# 问题,他可以简单地“单击标签”并将它们过滤掉。见stackoverflow.com/help/tagging -> Should I use tags in titles?
  • @chrfin 感谢您的回复和链接。就我个人而言,我发现在标题中添加标签比在问题下方更容易识别,但如果它是 stackoverflow 的指导方针,我会适应。
  • 我也有同样的偏好,但如果你习惯了这个“标签系统”,你就会开始喜欢它;)...

标签: c# asp.net asp.net-mvc asp.net-web-api controller


【解决方案1】:

给大家的提示:当你非常非常累的时候不要继续编程。无论如何,除了一个小缺陷之外,一切都是正确的:

我的 API 控制器称为 ProductsController,而我的普通(默认)控制器称为 ProductController。在上面我使用的方法中:

var url = "~/Products";

访问 ProductController..

所以,在删除“s”之后(并且为了更好地使所有内容都小写),我有以下内容:

var url = "~/product";

现在它可以工作了..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-28
    • 2013-08-20
    • 2016-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    相关资源
    最近更新 更多