2010-09-01 124 views
0

我試圖在託管的Windows服務中託管WCF服務。基本上我有1個解決方案CustomersWCFLibrary其中包含3個項目。我如何在Windows服務中託管WCF服務?

1)CustomersWCFLibrary: -

這是我的app.config: -

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 

    <configSections> 
    </configSections> 
    <connectionStrings> 
    <add name="CustomersWCFLibrary.Properties.Settings.NorthWindConnectionString" 
     connectionString="Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True" 
     providerName="System.Data.SqlClient" /> 
    </connectionStrings> 
    <system.web> 
    <compilation debug="true" /> 
    </system.web> 
    <!-- When deploying the service library project, the content of the config file must be added to the host's 
    app.config file. System.Configuration does not support config files for libraries. --> 
    <system.serviceModel> 

    <services> 
     <service name="CustomersWCFLibrary.CustomersService" behaviorConfiguration="ServiceBehavior"> 
     <endpoint address="net.tcp://localhost:9000/CustomersService" binding="netTcpBinding" contract="CustomersWCFLibrary.ICustomersService"> 
      <identity> 
      <dns value="localhost" /> 
      </identity> 
     </endpoint> 
     <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> 
     <host> 
      <baseAddresses> 
      <add baseAddress="net.tcp://localhost:9001/" /> 
      </baseAddresses> 
     </host> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="ServiceBehavior"> 
      <!-- To avoid disclosing metadata information, 
      set the value below to false and remove the metadata endpoint above before deployment --> 
      <serviceMetadata httpGetEnabled="false"/> 
      <!-- To receive exception details in faults for debugging purposes, 
      set the value below to true. Set to false before deployment 
      to avoid disclosing exception information --> 
      <serviceDebug includeExceptionDetailInFaults="False" /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 

</configuration> 

我的類: -

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.Text; 
using System.Data; 
using System.Data.SqlClient; 
using System.Collections; 

namespace CustomersWCFLibrary 
{ 
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in both code and config file together. 
    public class CustomersService : ICustomersService 
    { 
     public List<Customers> GetAllCustomers() 
     { 
      List<Customers> customersList = new List<Customers>(); 
      using (SqlConnection objSqlConnection = new SqlConnection(Properties.Settings.Default.NorthWindConnectionString)) 
      { 
       objSqlConnection.Open(); 
       SqlCommand objSqlCommand = new SqlCommand("Select CustomerID, ContactName, ContactTitle,CompanyName,Address from Customers",objSqlConnection); 
       SqlDataReader objSqlDataReader = objSqlCommand.ExecuteReader(); 

       while (objSqlDataReader.Read()) 
       { 
        string customerID = objSqlDataReader.GetString(0); 
        string contactName = objSqlDataReader.GetString(1); 
        string contactTitle = objSqlDataReader.GetString(2); 
        string companyName = objSqlDataReader.GetString(3); 
        string Address = objSqlDataReader.GetString(4); 
        Customers objCustomers = new Customers(); 
        objCustomers.CustomerId = customerID; 
        objCustomers.ContactName = contactName; 
        objCustomers.ContactTitle = contactTitle; 
        objCustomers.CompanyName = companyName; 
        objCustomers.Address = Address; 

        customersList.Add(objCustomers); 
       } 
      } 
      return customersList; 
     } 
    } 
} 

我的合同: -

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.Text; 

namespace CustomersWCFLibrary 
{ 
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together. 
    [ServiceContract] 
    public interface ICustomersService 
    { 
     [OperationContract] 
     List<Customers> GetAllCustomers(); 


     // TODO: Add your service operations here 
    } 

    // Use a data contract as illustrated in the sample below to add composite types to service operations 
    [DataContract] 
    public class Customers 
    { 

     [DataMember] 
     public string CustomerId 
     { get; set; } 

     [DataMember] 
     public string ContactName 
     {get; set;} 

     [DataMember] 
     public string ContactTitle 
     {get; set;} 

     [DataMember] 
     public string CompanyName 
     {get; set;} 

     [DataMember] 
     public string Address 
     {get; set;} 


    } 
} 

2)CustomersWindowsService

App.config中: -

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <system.serviceModel> 
     <services> 
      <service name="CustomersWCFLibrary.CustomersService"> 

       <endpoint address="net.tcp://localhost:9000/CustomersService" 
          binding="netTcpBinding" 
        bindingConfiguration="" name="CustomersService_Tcp" contract="CustomersWCFLibrary.ICustomersService" /> 

      </service> 
     </services> 
    </system.serviceModel> 
</configuration> 

這是我的窗口服務的代碼: -

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Diagnostics; 
using System.Linq; 
using System.ServiceProcess; 
using System.Text; 
using System.ServiceModel; 

namespace CustomersWindowsService 
{ 
    public partial class CustomersServiceWinService : ServiceBase 
    { 

     private ServiceHost host = null; 

     public CustomersServiceWinService() 
     { 
      InitializeComponent(); 
     } 

     protected override void OnStart(string[] args) 
     { 

       host = new ServiceHost(typeof(CustomersWCFLibrary.CustomersService)); 
       host.Open(); 

     } 

     protected override void OnStop() 
     { 
      host.Close(); 
     } 
    } 
} 

3)我的控制檯應用程序WCFCustomersTest

App.Config中: -

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <system.serviceModel> 
     <bindings /> 
     <client> 
      <endpoint address="net.tcp://localhost:9000/CustomersService" 
       binding="netTcpBinding" bindingConfiguration="" contract="CustomersWCFLibrary.ICustomersService" 
       name="CustomersService_Tcp" kind="" endpointConfiguration="" /> 
     </client> 
    </system.serviceModel> 
</configuration> 

Program.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.ServiceModel; 


namespace WCFCustomersTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var channel = new ChannelFactory<CustomersWCFLibrary.ICustomersService>("CustomersService_Tcp").CreateChannel(); 
      List<CustomersWCFLibrary.Customers> objList = channel.GetAllCustomers(); 
      Console.Write(objList.Count); 
      Console.Read(); 

     } 
    } 
} 

我的控制檯應用程序包含對WCFClassLibrary(第一個項目)的引用。 1)如果我不啓動我的Windows服務並在VS 2010中運行它,我會得到正確的輸出。但是,如果我從VS外部運行我的應用程序,我會得到一個很長的奇怪異常。

2)如果我開始我的Windows服務,我試圖從內VS或VS外面跑我的應用我得到這個錯誤: -

System.ServiceModel.FaultException was unhandled 
    Message=The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs. 
    Source=mscorlib 
    Action=http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher/fault 
    StackTrace: 
    Server stack trace: 
     at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter) 
     at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc) 
     at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) 
     at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) 
     at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) 
    Exception rethrown at [0]: 
     at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) 
     at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type) 
     at CustomersWCFLibrary.ICustomersService.GetAllCustomers() 
     at WCFCustomersTest.Program.Main(String[] args) in C:\Users\abc\documents\visual studio 2010\Projects\CustomersWCFLibrary\WCFCustomersTest\Program.cs:line 15 
     at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 

我試圖解決,已有3個小時沒有任何這樣的錯誤成功。

感謝提前:)例外

+0

你確定這是所有的代碼? ; P – leppie 2010-09-01 10:12:53

+0

wall ... of ... code ... – hydrogen 2010-09-01 10:15:00

+0

我建議你的windows服務無法連接到數據庫。打開WCF跟蹤 - http://msdn.microsoft.com/en-us/library/ms733025.aspx – 2010-09-01 10:17:20

回答

1

我建議兩件事troubleshoting問題,

  1. 啓用includeExceptionDetailInFaults,得到的反應更多的細節。
  2. 啓用WCF跟蹤,因爲您可能會在跟蹤中找到更多詳細信息。

如果我能看到有關錯誤的更多詳細信息,我將能夠提供更多幫助。你在那裏發佈的錯誤是一個通用的錯誤。

謝謝 Pablo。

+0

我知道這有點晚,但值得注意的是,如果打開跟蹤,只能用於調試目的。請務必在生產中關閉它,因爲它使用相當相當的資源,並且會減慢服務速度。 – Zannjaminderson 2011-03-22 19:02:18

1

屯詳情點擊這裏:< serviceDebug includeExceptionDetailInFaults =「真」/>

或調試未來的管理窗口服務端的請求,看看有什麼故障發生的事情。