0

IIS を備えたサーバーでホストされる WCF サービスの作成を初めて試みています。このサービスは、SQL データベースからデータを取得するために別のクラスに依存するため、Castle Windsor を使用して IoC を介して疎結合を維持しようとしています。

WCF サービスのさまざまな側面を以下に示します (C#er の方には事前に申し訳ありませんが、私は VB マンです!)。

サービス契約

<ServiceContract()> _
Public Interface IGetRiskDataService

    <OperationContract()>
    Function GetRisksByInsuredOpenBoxID(ByVal openBoxID As String) As List(Of Risk)

End Interface

Riskは、データベースから取得したデータを格納するために使用する独自のクラスです。

サービス契約の実施

Public Class GetRiskDataService : Implements IGetRiskDataService

    Private _rep As IDataWarehouseRepository

    Public Sub New(ByVal rep As IDataWarehouseRepository)
        _rep = rep
    End Sub

    Public Function GetRisksByInsuredOpenBoxID(openBoxID As String) As List(Of Risk) Implements IGetRiskDataService.GetRisksByInsuredOpenBoxID
        Return _rep.GetRisksByInsuredOpenBoxID(CType(openBoxID, Integer))
    End Function
End Class

ご覧のとおり、SQL データベースからデータを取得するために使用するクラスを WCF サービスのコンストラクターに挿入しています。

svc ファイル

<% @ServiceHost Service="DataWarehouseWCFService.GetRiskDataService" Factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration" %>

App.config ファイル

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

  <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 behaviorConfiguration="DataWarehouseWCFService.GetRiskDataServiceBehavior"
    name="DataWarehouseWCFService.GetRiskDataService">
        <!--<endpoint address="" binding="wsHttpBinding" contract="DataWarehouseWCFService.IGetRiskDataService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>-->
    <!--<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />-->
    <endpoint address="../GetRiskDataService.svc"
       binding="webHttpBinding"
       contract="DataWarehouseWCFService.IGetRiskDataService"
       behaviorConfiguration="webBehaviour" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8732/Design_Time_Addresses/DataWarehouseWCFService/GetRiskDataService/" />
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="DataWarehouseWCFService.GetRiskDataServiceBehavior">
      <!-- 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="True" />
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="webBehaviour">
      <webHttp/>
    </behavior>
  </endpointBehaviors>
</behaviors>
  </system.serviceModel>

</configuration>

おそらく、ほとんどそのままにしておいた App.config ファイルを除いて、ここにあるものはすべて問題ないと思います。

次に、サービスをホストする IIS サーバー上に常駐する基本的な ASP.Net Web アプリケーションを作成しました。Web アプリケーションでは、global.asax ファイルは次のようになります。

Private _container As IWindsorContainer
Private _sqlConnection As String = "Data Source=[Server Name];Integrated Security=SSPI;Initial Catalog=[Database Name];"

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
    ' Fires when the application is started

    _container = New WindsorContainer

    _container.AddFacility(Of WcfFacility).Register(Component.For(Of IDataWarehouseRepository).ImplementedBy(Of SQLDataWarehouseRepository).DependsOn(Dependency.OnValue("connect", _sqlConnection)), _
                                                    Component.For(Of IGetRiskDataService).ImplementedBy(Of GetRiskDataService))

End Sub

そのため、ここでは SQL データ取得クラスへの依存関係を含めて、Castle Windsor にサービスを登録します。うまくいけば、これまでのところ、とても良い...

このホスティング アプリケーションを IIS サーバーに問題なく展開してインストールしました。

後は、クライアント アプリケーションでサービスを使用するだけですが、ここで行き詰まりました。ビューにデータを表示するために Web サービスを使用したい MVC4 アプリケーションがあります。このアプリケーションでは既に Castle Windsor を使用して他の依存関係を登録しているため、必要な Castle Windsor インフラストラクチャはすべて既に存在しています。したがって、私が必要だと思ったのは、Web サービスのインストーラーだけでした。これに対する私の試みは以下のとおりです。

Public Class DataWarehouseWebServicesInstaller : Implements IWindsorInstaller

Private Const _getRiskDataServiceEndpoint As String = "http://[Server Name].[Domain Name]/Data Warehouse Web Services/GetRiskDataService.svc"

Public Sub Install(container As Castle.Windsor.IWindsorContainer, store As Castle.MicroKernel.SubSystems.Configuration.IConfigurationStore) Implements Castle.MicroKernel.Registration.IWindsorInstaller.Install
    'Data Warehouse Web Services
    container.Register(Component.For(Of IEndpointBehavior).ImplementedBy(Of WebHttpBehavior))
    container.AddFacility(Of WcfFacility).Register( _
                                            Component.For(Of IGetRiskDataService).AsWcfClient( _
                                                New DefaultClientModel( _
                                                    WcfEndpoint.BoundTo(New WebHttpBinding).At(_getRiskDataServiceEndpoint) _
                                                    ) _
                                                ) _
                                            )
End Sub
End Class

最後に、いくつかのテスト コードをコントローラーに追加して、WCF サービスが機能するかどうかを確認しました。

    Public Sub New(ByVal ash As IGetRiskDataService)
        Dim lozza = ash.GetRisksByInsuredOpenBoxID(100005859)
        For Each lianne As Risk In lozza
            Dim neil As Date = lianne.ExpiryDate.CalendarDate
        Next
    End Sub

これをテストすると、次のエラーが発生します。

{"The remote server returned an error: (415) Cannot process the message because the content type 'application/xml; charset=utf-8' was not the expected type 'text/xml; charset=utf-8'.."}. The client and service bindings may be mismatched.

これは私が迷っているところです。クライアントとサービスのバインディングが一致しない問題を調査しましたが、残念ながら、ほとんどすべての回答が app.config ファイルでこれらのバインディングが指定されていることに言及しています。コードで実行したい構成。たとえば、私のインストーラー コードでは、エンドポイントを WebHttpBinding に登録します。

私はこれに近いと感じていますが、ことわざのレンガの壁にぶつかっています. どんな助けでも喜んでいただければ幸いです。他に提供できる情報があれば教えてください。

どうもありがとう、

4

1 に答える 1

0

このエラーは、サービスで何かが誤って構成されている場合のかなり一般的なエラーです。サービスがまったく適切に実行されておらず、標準の wcf html エラー ページが返されます。クライアントは SOAP 応答を期待していますが、取得するのはエラー html だけです。

実際に間違っていることを解決するには、ブラウザでサービスに移動する必要があります

http://localhost:8732/Design_Time_Addresses/DataWarehouseWCFService/GetRiskDataService/GetRiskDataService.svc

ここに表示されるエラー メッセージは、よりわかりやすいものです。

これまでの投稿を見てみると、関連している可能性があります...

  • Risk クラスは、DataMember 属性を持つ DataContract としてマークアップされていますか?
  • おそらく、エンドポイント アドレスの address="../GetRiskDataService.svc" の部分は必要ありません。
于 2013-09-21T08:34:00.733 に答える