WCF + MVC + Web API处理程序和路由

时间:2014-01-29 00:28:34

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

我最近将Visual Studio升级到2013,现在默认使用IIS Express(而不是Cassini),发现我无法再点击我的WCF服务javascript端点:Myservice.svc / js或/ jsdebug,但是点击了.svc直接工作正常。

我发现如果删除< handlers>我的web.config部分(包括一些ExtensionlessUrlHandler项),恢复了脚本端点的功能。我很好奇删除以下项目的后果是什么,以及是否有替代解决方案。

这是我从Web.config中删除的块:

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <remove name="OPTIONSVerbHandler" />
  <remove name="TRACEVerbHandler" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

某些上下文,我在一个项目中使用.NET 4.5,MVC 5.1,WebAPI v2.1和WCF。基本上是所有组件的最新版本。

更新1: 我也注意到任何WebAPI PUT都会以404删除这些处理程序而回归;所以显然缺少某些东西。另一个小的顿悟是,当部署到实时服务器(IIS 7.5 [Version 7.5.7600.16385])时,一切都很好。因此,Visual Studio 2013集成版本的IIS Express和完整的IIS 7.5设置的路由或处理程序映射必须有所不同。

另外,如果我创建一个全新的ASP.NET Web应用程序并添加WCF服务,一切都在本地工作正常。如果我然后添加一个WebAPI控制器,下面的处理程序部分将添加到web.config并中断所有WCF调用。当MVC,WCF和WebAPI都是一个应用程序的一部分时,这使得它听起来更像是Microsoft默认配置中的“错误”。

更新2: 这是一个基本的测试用例,任何人都可以遵循以重现我遇到的错误。

重新创建基本问题的流程: (WebAPI正在工作,WCF * .svc / js导致404)

  1. 新项目 - &gt; Asp.NET Web应用程序,使用Web API模板(包括MVC和Web API引用)
  2. 将新的“WCF服务(启用ajax)添加到名为”TestService“的项目根目录
  3. 启动项目。
  4. 验证/ help路由是否适用于MVC(呈现帮助页面)
  5. 验证GET / api / values / 1是否适用于WebApi(返回值)
  6. *确认PUT / api / values / 1适用于WebApi(不返回任何内容 - 无效方法)*
  7. 验证可以为WCF命中TestService.svc(显示元数据页面)
  8. *验证TestService.svc / js FAILS带有404 for WCF - 路由问题! *
  9. 部分修复: (WebAPI PUT坏了,WCF可以呈现JS请求)

    1. 从上面继续......
    2. 更新Web.config并注释掉&lt;处理程序&gt;节
    3. 启动项目。
    4. 验证/ help路由是否适用于MVC(呈现帮助页面)
    5. 验证GET / api / values / 1是否适用于WebApi(返回值)
    6. *验证PUT / api / values / 1 FAILS与404 for WebApi - 路由问题! *
    7. 验证可以为WCF命中TestService.svc(显示元数据页面)
    8. *验证TestService.svc / js为WCF呈现必要的JavaScript *

1 个答案:

答案 0 :(得分:3)

这实际上是一个mvc路由问题。请修改你的〜/ App_Start / RouteConfig.cs,如下所示。您需要保留ExtensionlessUrlHandler,以便mvc路由在无扩展名网址上正常运行。

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        //This line is the addition.
        routes.IgnoreRoute("{resource}.svc/{*pathInfo}");

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