问题
I am trying to deploy a Windows desktop application with service layer, logic layer and data layer. The data layer uses SQL Server with EF 6.2. The UI client layer is a Windows Forms application.
The application works great in test debug mode when the service is hosted by the WcfSvcUtil.exe
application with a service alias in IIS - no errors and all data retrieval and updates are working in test.
Now, I have published the Service layer, logic layer and data layer as an empty web site to be hosted by IIS on my local machine (c:/inetpub/wwwroot/) in the "alias" subfolder. I created an IIS application named with the alias name for the service. The UI layer and Service layer are published to a different local folder on my machine.
When I start the UI layer, and try to query the SQL Server database, I get the following error:
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.
My Service Model element in the web.config
in the hosted web site is:
<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>
I'm new to WCF and Entity Framework so any suggestions would be appreciated. I also have an app.config
and web.config
in the Service layer, and app.config
in the UI layer. I can post those if you think they will be helpful, but for the IIS web.config
shown, I basically combined the endpoints from the Service layer's config files to be published to the IIS web site.
** Changed my web.config file as below **
***
<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>
***
Also, when I browse to http://localhost/TheACTSFactoryWCFLocal/MemberService.svc, my Service is found.
The following s the App.config in UI layer:
***
<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>
***
Here is the IIS server folder named as the Alias name of the IIS app, there is not SVC file
Here are the DLL's, etc, published to the Bin folder
Does the IIS Server's Alias/Bin folder deployment look normal for a WCF service hosted in IIS 10.0 in .NET 4.5.2? Also, I did not publish anything to the Roslyn folder (CodeDom). Any comments or suggestions?
回答1:
According to your description, I found that when you publish the service to IIS, the host tag still exists in your configuration file. Only self hosted or hosted programs like windows service need to configure host. When you host the service in IIS, the base address of the service is composed of the port number deployed in IIS and the file name of the service.
This is the configuration file of WCF service deployed in IIS.
I set the port number of the service to 8063.
Access this address and we will see the directory of the service.
Click service1.scv to see that the service starts normally.At this time, "localhost:8063/Service1.svc" in the address bar is the address of the service. The client needs to access this address to succeed.
update
If your project is deployed in IIS, I suggest using WCF service application template when creating a project.
The structure directory after the creation is like this:
Service1 is the implementation class of a service.
回答2:
I could not get the IIS-hosted solution to deploy, so I changed my strategy to using a Self-Hosting Windows Forms project as the hosting application.
I changed my Service project from a VS2017 .NET4.5.2 WCF Service Library template to a WCF Service Application template, and was more successful in getting my total solution to work in development/debug mode. However, I was not able to publish/deploy my solution properly to have IIS host the Service. So, I changed to using a Windows Forms "self-hosting" method instead. This suits my ultimate goal of being able to use Windows Forms controls, and it will work well for the intended users group for now.
Here is what I did:
Changed my Service project to WCF Service Application template.
In .NET 4.5.2, the *.SVC file is not required, but Interface and Implementation are.
Removed IIS Host Solution folder, added Windows Forms project as Service Hosting app.
Copied Service' Web.config to HostWinFormsApp project, renamed it App.config.
Made changes to the Hosting project's App.config to have "serviceHostingEnvironment" section
Added "serviceActivations" section to it, pointing to base address in Hosting project Like this: relativeAddress="./HostWinFormsApp/MemberService.svc"
Added almost the same to Web.config in Service project, but with the simple relativeAddress="./MemberService.svc" only
With HostWinFormsApp and the Service app's configuration files corrected, I was able start the Service, run SVCUTIL.exe and create my Service Proxy for the UI. This utility also updated the UI Client's app.config with the Endpoint address: <endpoint address="http://localhost:port#/HostWinFormsApp/MemberService.svc"
Added ServiceHost object to the HostWinFormsApp.Program.cs Main() function to host and start the WCF Service "ACTSFactoryWCFServiceApp.MemberService".
Added System.Diagnostic.Process to UI client's Program.cs Main() function to launch the hosting application, HostWinFormsApp, before "running" the UI Client's winform (Form1).
With configuration files corrected, the new HostWinFormsApp project in place with a ServiceHost object defined and the UI Client project starting the HostWinFormsApp, I was ready to test.
Set the HostWinFormsApp and UI Client to both be startup projects, and ctrl-F5 to test. Both winforms started, Hosting project first, then client.
Changed Startup project to UI Client only, and Ctrl-F5. Both winforms started, hosting first and client second. Client requested and received data in the ADGView control.
In UI Client, Service and HostWinFormsApp projects' Properties page "Build events - Post-build" option, added command to copy DLL files from bin\debug up one level to .\bin folder. Cleaned and re-built Solution. (copy .\*.* ..\*.*)
Right-clicked on the Service project, published to target folder. publishing-folder\bin was created including all DLL's from Service project copied to .\bin. Service's Web.config was copied to publishing-folder.
Published HostWinFormsApp project, as StartUpProject, to same pub-folder. Setup.exe, HostWinFormsApp.application and the subfolder "Application" were created in pub-folder. Host project's DLL's were copied to "Application" folder.
Renamed "setup.exe" to "Host.exe" and Ran as Administrator to complete setup.
Published ACTSFactoryUI (Windows Forms) client project to pub-folder as StartUpProject. Setup.exe, ACTSFactoryUI.application were created, and ACTSFactoryUI project DLL's went into the "Application" folder.
Renamed "Setup.exe" to "Client.exe" and double-clicked to complete setup.
Created a "RunApps.bat" file to start both apps. Created a desktop Shortcut to the c:\pub-folder\RunApps.bat, edited "Advanced" in Shortcut to Run As Administrator.
Double-Clicked the Shortcut and Host.exe and Client.exe launched.
Screenshot below shows Service, UI Client, deployment folder and "Shortcut" icon on desktop.
- The next pic shows the hosting WinForms project's Program.cs class. In this class, the ServiceHost object is defined, with the Service type and the base address of the Service, and then the Service Host is opened - which starts the Service running (listening) for requests.
- Once this (localdb) deployment was completed, I had to remove and reload my EntityFramework and rebuild the entity model class in the DAL layer using the Remote database as my source. Once the new connection & Entity Model for the remote database was completed, and all config files updated with new connectionString, I redeployed in same manner as above to my laptop - with the locally installed Service accessing the Remote database now. This was an EF DB Model First implementation. SQL Server database was built in MS SSMS.
来源:https://stackoverflow.com/questions/62014065/wcf-ef-sql-server-vs2017-c-sharp-multi-tier-application-gets-error-whe