WCF / EF / SQL Server / VS2017 / C#:多层应用程序在作为托管服务器部署到本地 IIS 10.0 时出错

WCF / EF / SQL Server / VS2017 / C# : multi-tier application gets error when deployed to local IIS 10.0 as hosting server

我正在尝试部署具有服务层、逻辑层和数据层的 Windows 桌面应用程序。数据层使用 SQL 服务器和 EF 6.2。 UI 客户端层是一个 Windows 表单应用程序。

当服务由 IIS 中具有服务别名的 WcfSvcUtil.exe 应用程序托管时,该应用程序在测试调试模式下运行良好 - 没有错误,所有数据检索和更新都在测试中运行。

现在,我已将服务层、逻辑层和数据层发布为一个空网站,由 IIS 在我的本地计算机 (c:/inetpub/wwwroot/) 中托管 "alias"子文件夹。我创建了一个以该服务的别名命名的 IIS 应用程序。 UI 层和服务层发布到我机器上的不同本地文件夹。

当我启动 UI 层并尝试查询 SQL 服务器数据库时,出现以下错误:

There was no endpoint listening at http://localhost/TheACTSFactoryWCFLocal/MemberService/ that could accept the message. This is often caused by an incorrect address or SOAP action. See innerException, if present, for more details.

托管网站 web.config 中我的服务模型元素是:

<system.serviceModel>
    <services>
        <service name="ACTSFactoryService.MemberService">
            <endpoint name="BasicHttpBinding_IMemberService"
                address="" 
                binding="basicHttpBinding" 
                contract="ACTSFactoryService.IMemberService" >
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
            <endpoint 
                address="mex" 
                binding="mexHttpBinding" 
                contract="IMetadataExchange" />
            <host>
                <baseAddresses>
                    <add baseAddress="http://localhost/TheACTSFactoryWCFLocal/MemberService/" />
                </baseAddresses>
            </host>
        </service>
    </services>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true">
        <serviceActivations>
            <add factory="System.ServiceModel.Activation.ServiceHostFactory" 
                 relativeAddress="./MemberService.svc" 
                 service="ACTSFactoryService.MemberService" />
        </serviceActivations>
    </serviceHostingEnvironment>
    <behaviors>
        <serviceBehaviors>
            <behavior>
                <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
                <serviceDebug includeExceptionDetailInFaults="True" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_IMemberService" 
                     maxReceivedMessageSize="20000000" maxBufferSize="20000000" />
        </basicHttpBinding>
    </bindings>
</system.serviceModel>

我是 WCF 的新手并且 Entity Framework 所以任何建议都将不胜感激。我在服务层也有一个 app.configweb.config,在 UI 层有一个 app.config。如果您认为它们会有帮助,我可以 post,但是对于显示的 IIS web.config,我基本上结合了服务层配置文件中的端点以发布到 IIS 网站。

** 更改了我的 web.config 文件如下 **

***

<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.5.2" />
  </system.web>

  <system.serviceModel >   
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" >
      <serviceActivations > 
        <add factory ="System.ServiceModel.Activation.ServiceHostFactory"
                relativeAddress="./MemberService.svc"
                service="ACTSFactoryService.MemberService" />
     </serviceActivations> 
    </serviceHostingEnvironment>

    <behaviors >
      <serviceBehaviors >
        <behavior >
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

***

此外,当我浏览到 http://localhost/TheACTSFactoryWCFLocal/MemberService.svc 时,我的服务被发现了。

下面是UI层的App.config:

***
 <configuration>
   <startup>
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
   </startup>
   <system.serviceModel>
     <bindings>
       <basicHttpBinding>
         <binding name="BasicHttpBinding_IMemberService"      maxBufferSize="20000000"
           maxReceivedMessageSize="20000000" />
       </basicHttpBinding>
     </bindings>
     <client>
       <endpoint address="http://localhost/TheACTSFactoryWCFLocal/MemberService/"
         binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMemberService"
         contract="MemberServiceProxy.IMemberService" />
     </client>
   </system.serviceModel>
 </configuration>
***

这里是IIS服务器文件夹,以IIS应用的别名命名,没有SVC文件

这是发布到 Bin 文件夹的 DLL 等

对于 .NET 4.5.2 中 IIS 10.0 中托管的 WCF 服务,IIS 服务器的 Alias/Bin 文件夹部署看起来是否正常?此外,我没有向 Roslyn 文件夹 (CodeDom) 发布任何内容。有什么意见或建议吗?

根据您的描述,我发现当您将服务发布到IIS时,您的配置文件中仍然存在host标签。只有像 windows 服务这样的自托管或托管程序需要配置主机。当你在IIS中托管服务时,服务的基地址由IIS中部署的端口号和服务的文件名组成。

这是部署在IIS中的WCF服务的配置文件。

我把服务的端口号设置为8063

访问这个地址,我们会看到服务的目录。

点击service1.scv可以看到这次服务启动了normally.At,地址栏中的"localhost:8063/Service1.svc"是服务的地址。客户端需要访问这个地址才能成功。

更新

如果你的项目部署在IIS中,我建议在创建项目时使用WCF服务应用模板。

创建后的结构目录是这样的:

Service1 是服务的实现class。

我无法部署 IIS 托管解决方案,因此我将策略更改为使用自托管 Windows Forms 项目作为托管应用程序。

我将我的服务项目从 VS2017 .NET4.5.2 WCF 服务库模板更改为 WCF 服务应用程序模板,并且更成功地让我的整体解决方案在 development/debug 模式下工作。 但是,我无法 publish/deploy 我的解决方案正确地让 IIS 托管服务。 所以,我改为使用 Windows 表单“自托管”方法。 这符合我能够使用 Windows 表单控件的最终目标,并且它现在对预期的用户组来说效果很好。

这是我所做的:

  1. 将我的服务项目更改为 WCF 服务应用程序模板。

  2. 在 .NET 4.5.2 中,*.SVC 文件不是必需的,但接口和实现是必需的。

  3. 删除了 IIS 主机解决方案文件夹,添加了 Windows Forms 项目作为服务托管应用程序。

  4. 复制服务' Web.config 到 HostWinFormsApp 项目,重命名为 App.config.

  5. 对托管项目的 App.config 进行了更改,使其具有 “服务托管环境”部分

  6. 添加了“serviceActivations”部分,指向托管项目中的基地址 像这样:relativeAddress="./HostWinFormsApp/MemberService.svc"

  7. 在服务项目中添加了几乎与 Web.config 相同的内容,但使用了简单的 relativeAddress="./MemberService.svc" 仅

  8. 通过更正 HostWinFormsApp 和服务应用程序的配置文件,我能够 启动服务 运行 SVCUTIL.exe 并为 UI 创建我的服务代理。这个 实用程序还使用端点地址更新了 UI 客户端的 app.config: <端点地址="http://localhost:port#/HostWinFormsApp/MemberService.svc"

  9. 将 ServiceHost 对象添加到 HostWinFormsApp.Program.cs Main() 函数以托管和启动 WCF 服务“ACTSFactoryWCFServiceApp.MemberService”。

  10. 添加 System.Diagnostic.Process 到 UI 客户端的 Program.cs 要启动的 Main() 函数 托管应用程序 HostWinFormsApp,在“运行ning” UI 客户端的 winform 之前 (Form1).

  11. 配置文件更正后,新的 HostWinFormsApp 项目就位 定义了一个 ServiceHost 对象并且 UI 客户端项目启动了 HostWinFormsApp,我准备测试了。

  12. 将 HostWinFormsApp 和 UI 客户端设置为启动项目,然后按 ctrl-F5 去测试。两个winform都启动了,先是Hosting project,然后是client。

  13. 将启动项目更改为 UI 仅限客户端,以及 Ctrl-F5。两个winform都启动了, 首先托管,然后再托管客户端。客户端在 ADGView 中请求和接收数据 控制。

  14. 在 UI 客户端、服务和 HostWinFormsApp 项目的属性页面“构建事件 - Post-build" 选项,添加了从 bin\debug 向上一级复制 DLL 文件的命令 到 .\bin 文件夹。清理并重建解决方案。 (复制.\*.* ..\*.*)

  15. 右键单击服务项目,发布到目标文件夹。 publishing-folder\bin 是 创建包括从服务项目复制到 .\bin 的所有 DLL。服务 Web.config 已复制到发布文件夹。

  16. 已将 HostWinFormsApp 项目作为 StartUpProject 发布到同一发布文件夹。 Setup.exe, HostWinFormsApp.application 和子文件夹“应用程序”已在 pub 文件夹中创建。 宿主项目的 DLL 被复制到“应用程序” 文件夹。

  17. 已将“setup.exe”重命名为“Host.exe”并运行作为管理员完成设置。

  18. 已将 ACTSFactoryUI(Windows 表单)客户端项目作为 StartUpProject 发布到 pub 文件夹。 Setup.exe, ACTSFactoryUI.application 已创建,ACTSFactoryUI 项目 DLL 进入“​​应用程序”文件夹。

  19. 将“Setup.exe”重命名为“Client.exe”并双击完成设置。

  20. 创建了一个“RunApps.bat”文件来启动这两个应用程序。创建了 c:\pub-folder\RunApps.bat 的桌面快捷方式,将快捷方式中的“高级”编辑为 运行 作为管理员。

  21. 双击快捷方式并启动 Host.exe 和 Client.exe。

  22. 下面的屏幕截图显示了服务、UI 客户端、部署文件夹和桌面上的“快捷方式”图标。

  1. 下一张图片显示了托管 WinForms 项目的 Program.cs class。在这个class中, ServiceHost 对象被定义,具有服务类型和基址 服务,然后打开服务主机 - 启动服务 运行ning (侦听)请求。

  1. 此 (localdb) 部署完成后,我必须删除并重新加载我的 EntityFramework 并使用远程数据库作为我的源在 DAL 层中重建实体模型 class。一旦远程数据库的新连接和实体模型完成,并且所有配置文件都更新了新的 connectionString,我以与上面相同的方式重新部署到我的笔记本电脑 - 现在本地安装的服务正在访问远程数据库。这是一个 EF DB Model First 实现。 SQL 服务器数据库是在 MS SSMS 中构建的。