【问题标题】:Hosting a WCF Service in an MVC application outside of Areas在区域外的 MVC 应用程序中托管 WCF 服务
【发布时间】:2012-12-18 17:57:14
【问题描述】:

我有一个 MVC 项目,我在根目录中添加了一个名为 WCF 的文件夹。在此文件夹中,我创建了一个名为 CustomFunctions 的 WCF 服务。当我尝试启动服务时,我收到以下错误:

错误:无法从http://localhost/Viper/WCF/CustomFunctions.svc 获取元数据...元数据包含无法解析的引用:

附加说明:

找不到类型“Viper.WCF.CustomFunctions”,作为 ServiceHost 指令中的服务属性值提供,或在配置元素 system.serviceModel/serviceHostingEnvironment/serviceActivations 中提供。

我昨天遇到了这个错误,并花了一些时间在互联网上寻找答案。这导致我对我的 Web.config 和 Global.asax.cs 进行了很多更改。昨天的某个时候,它开始工作,我停止了。然而,当我今天早上回来时,它并没有重新开始工作。在此期间没有添加任何新内容,也没有更改任何代码。

我已将以下内容添加到我的 Web.config:

<system.serviceModel>
<services>
  <service behaviorConfiguration="WCFBehavior" name="Viper.WCF.CustomFunctions">
    <endpoint address="" binding="wsHttpBinding" contract="Viper.WCF.ICustomFunctions">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost/Viper/WCF/CustomFunctions/" />
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="WCFBehavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" httpGetUrl=""/>
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel> 

这是我的Global.asax.cs:

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

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new
            {
                controller = "Home",
                action = "Index",
                id = UrlParameter.Optional
            }, // Parameter defaults
            new { controller = "^(?!CustomFunctions).*" }
        );

        routes.Add(new ServiceRoute("CustomFunctions", new ServiceHostFactory(),
                   typeof(CustomFunctions)));
    }

谁能帮帮我?我在这里完全没有想法。

【问题讨论】:

  • 我不确定这是否可行(尽管我怀疑它是可行的),但您是否有某些理由不想要一条不同的路径?我们的 MVC 应用程序还使用 WCF 服务,我将其托管在同一个应用程序池中,但我只是选择不采用该路线,因为您现在面临的复杂情况,并且没有令人信服的理由让事情变得比他们需要的更困难是......但如果有人发布它,我会对解决方案感兴趣......
  • 我已经查看了有关路线的帖子,并按照我发布的 Global.asax.cs 代码中的说明进行了必要的更改。我们之所以要将 WCF 服务放在我们的 MVC 项目中,是因为我们不想在两个项目之间有单独的缓存。我们只想要一个。出于这个原因,我的主管希望我试着让它发挥得很好。但是,如果我不能快速解决问题,我可能会选择单独的项目,因为我知道它可以在 MVC 之外的 WCF 项目中使用。
  • 老实说,我对 MVC 路由还不是很熟悉,但是您在 .svc 上执行 IgnoreRoute 似乎很奇怪,然后创建了一个服务路由,我会假设会期待 CustomFunctions.svc。

标签: c# wcf web-services model-view-controller metadata


【解决方案1】:

我已经找到了问题所在。首先,我错过了注册我的路由的函数路径的一部分。修复该路径后,我能够让我的 wsdl 出现在我的托管环境中。但是,这弄乱了我所在区域的默认路由。因此,对于将来遇到此问题的任何人,这是我的解决方案:

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

        routes.MapRoute(
            "CustomFunctions", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new
            {
                controller = "CustomFunctions",
                action = "Index",
                id = UrlParameter.Optional
            }, // Parameter defaults
            new { controller = "^(?!CustomFunctions).*" }
        );

        routes.Add(new ServiceRoute("CustomFunctions", new ServiceHostFactory(),
                   typeof(CustomFunctions)));

        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");           

        // Had to do some special stuff here to get this to work using a default area and no controllers/view in the root
        routes.MapRoute(
            name: "Default",
            url: "{area}/{controller}/{action}/{id}",
            defaults: new { area = "", controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new string[] { "Viper.Areas.Home" }
        ).DataTokens.Add("area", "Home");           
    }

我主要指定了我的自定义路由,以便当我导航到指定的 url 时,它会显示我的 .svc 文件。我从 Global.asax.cs 中的 ApplicationStart 方法调用此方法。我还必须在我的 Home Area 中为我的 CustomFunctions 创建一个单独的控制器和视图,以便它可以区分我的默认路由和我的 CustomFunctions,并在我的路由图中指定它,如上所示。因此,当我转到 localhost\Viper 时,它会找到在我的默认地图中指定的路线,当我转到 localhost\Viper\CustomFunctions 时,它会找到我的 .svc 文件的路线。 IgnoreRoute 基本上做到了,因此您在调用页面时不必将文件扩展名放在 url 的末尾。所以我只指定 CustomFunctions 而不是 CustomFunctions.svc。确保在执行此操作时将 System.ServiceModel.Activation 程序集和 using 语句添加到您的项目中。

感谢大家的帮助。希望这可以帮助其他一些可怜的失落的灵魂。

【讨论】:

    猜你喜欢
    • 2016-08-14
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 2012-11-29
    • 2017-01-20
    • 1970-01-01
    • 2012-03-16
    相关资源
    最近更新 更多