2011-09-09 2 views
2

私は、そのサービスがつのエンドポイント(石鹸、JSON)と1つのサービスメソッド

 [OperationContract] 
    [WebGet(UriTemplate = "/GetData")] 
    List<FieldInfo> GetSerializedData(); 

とweb.configファイル

<system.web> 
    <webServices> 
     <protocols> 
     <add name="HttpGet" /> 
     <add name="HttpPost" /> 
     </protocols> 
    </webServices> 
    <httpRuntime executionTimeout="90" maxRequestLength="1048576" useFullyQualifiedRedirectUrl="false" minFreeThreads="8" minLocalRequestFreeThreads="4" appRequestQueueLimit="100"/> 
    <compilation debug="true" targetFramework="4.0"/> 
    </system.web> 
    <system.serviceModel> 
    <bindings> 
     <webHttpBinding> 
     <binding name="webHttpBindingSettings" maxBufferPoolSize="524288" maxReceivedMessageSize="654321" sendTimeout="00:10:00" closeTimeout="00:01:00" openTimeout="00:10:00" receiveTimeout="00:10:00"> 
      <security mode="None"> 
      <transport clientCredentialType="None" /> 
      </security> 
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 
     </binding> 
     </webHttpBinding> 
     <wsHttpBinding> 
     <binding name="wsHttpBindingSettings" maxBufferPoolSize="524288" maxReceivedMessageSize="654321" sendTimeout="00:10:00" closeTimeout="00:01:00" openTimeout="00:10:00" receiveTimeout="00:10:00"> 
      <security mode="None"> 
      <transport clientCredentialType="None" /> 
      </security> 
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 
     </binding> 
     </wsHttpBinding> 
    </bindings> 
    <services> 
     <service behaviorConfiguration="MetadataBehavior" name="ServiceModel.Service"> 
     <endpoint name="soap" address="soap" behaviorConfiguration="Default" binding="wsHttpBinding" 
      bindingConfiguration="wsHttpBindingSettings" contract="ServiceModel.IService" /> 
     <endpoint name="Json" address="json" behaviorConfiguration="JSON" binding="webHttpBinding" 
     bindingConfiguration="webHttpBindingSettings" contract="ServiceModel.IService" /> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     <host> 
      <baseAddresses> 
      <add baseAddress="http://service.com/Service.svc/" /> 
      </baseAddresses> 
     </host> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="MetadataBehavior"> 
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
      <serviceMetadata httpGetEnabled="true" /> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="JSON"> 
      <webHttp automaticFormatSelectionEnabled="true"/> 
      <dataContractSerializer maxItemsInObjectGraph="10000000"/> 
     </behavior> 
     <behavior name="Default"> 
      <dataContractSerializer maxItemsInObjectGraph="10000000"/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 

なぜクライアント側で唯一のエンドポイントが生成されますか?

<client> 
    <endpoint address="http://service.renault.com/Service.svc/soap" 
    binding="wsHttpBinding" bindingConfiguration="soap" contract="ServiceReference1.IService" 
    name="soap" /> 
</client> 

私のポイントは、石鹸やJSONでasp.netページの分離コードとWCFリターンデータからサービスメソッドを実行することですContentTypeを依存します。しかし、text/htmlコンテンツを持っている場合、asp.netページのコンテンツタイプをapplication/jsonに設定する方法。私はそれを理解することに問題がある。

+0

私は問題がクライアント側にあると思います。クライアントコールの詳細を投稿できますか? –

+0

クライアント側では、エンドポイントが1つしか生成されません - soap;/ – netmajor

答えて

1

可能ならば、このようにあなたのVisual Studioをデザインしよう:

  • ソリューション
    • 契約(のみIXXXXService)の実装と
    • Webプロジェクトとすべてのエンドポイントを持つプロジェクト(参照契約プロジェクト)
    • クライアントプロジェクトはVS生成プロキシを使用せず、正しいエンドポイントとそのプロトコルを選択できるファクトリを使用します。ここでは(契約のプロジェクトを参照)

は、私はあなたと同様のシナリオで使用するサンプルクラスです:クライアントの設定で

public class ServiceHelper 
{ 

    /// <summary> 
    /// WCF proxys do not clean up properly if they throw an exception. This method ensures that the service 
    /// proxy is handeled correctly. Do not call TService.Close() or TService.Abort() within the action lambda. 
    /// </summary> 
    /// <typeparam name="TService">The type of the service to use</typeparam> 
    /// <param name="action">Lambda of the action to performwith the service</param> 
    [System.Diagnostics.DebuggerStepThrough] 
    public static void UsingProxy<TService>(Action<TService> action) 
     where TService : ICommunicationObject, IDisposable, new() 
    { 
     var service = new TService(); 
     bool success = false; 
     try 
     { 
      action(service); 
      if (service.State != CommunicationState.Faulted) 
      { 
       service.Close(); 
       success = true; 
      } 
     } 
     finally 
     { 
      if (!success) 
      { 
       service.Abort(); 
      } 
     } 
    } 
    /// <summary> 
    /// WCF proxys do not clean up properly if they throw an exception. This method ensures that the service 
    /// proxy is handeled correctly. Do not call TService.Close() or TService.Abort() within the action lambda. 
    /// </summary> 
    /// <typeparam name="TIServiceContract">The type of the service contract to use</typeparam> 
    /// <param name="action">Action to perform with the client instance.</param> 
    /// <remarks>In the configuration, an endpoint with names that maches the <typeparamref name="TIServiceContract"/> name 
    /// must exists. Otherwise, use <see cref="UsingContract&lt;TIServiceContract&gt;(string endpointName, Action<TIServiceContract> action)"/>. </remarks> 
    [System.Diagnostics.DebuggerStepThrough] 
    public static void UsingContract<TIServiceContract>(Action<TIServiceContract> action) 
    { 
     UsingContract<TIServiceContract>(
      typeof(TIServiceContract).Name, 
      action 
      ); 
    } 
    /// <summary> 
    /// WCF proxys do not clean up properly if they throw an exception. This method ensures that the service 
    /// proxy is handeled correctly. Do not call TService.Close() or TService.Abort() within the action lambda. 
    /// </summary> 
    /// <typeparam name="TIServiceContract">The type of the service contract to use</typeparam> 
    /// <param name="action">Action to perform with the client instance.</param> 
    /// <param name="endpointName">Name of the endpoint to use</param> 
    [System.Diagnostics.DebuggerStepThrough] 
    public static void UsingContract<TIServiceContract>(
      string endpointName, 
      Action<TIServiceContract> action) 
    { 
     var cf = new ChannelFactory<TIServiceContract>(endpointName); 
     var channel = cf.CreateChannel(); 
     var clientChannel = (IClientChannel)channel; 

     bool success = false; 
     try 
     { 
      action(channel); 
      if (clientChannel.State != CommunicationState.Faulted) 
      { 
       clientChannel.Close(); 
       success = true; 
      } 
     } 
     finally 
     { 
      if (!success) clientChannel.Abort(); 
     } 
    } 
} 

、私は手動で私の参照を設定します

<system.serviceModel> 
<client> 
    <endpoint address="http://localhost/myapp/myservice.svc/soap" 
      binding="wsHttpBinding" 
      contract="MyProject.Contracts.IMyService" 
      name="IMyServiceSoap"/> 
    <endpoint address="http://localhost/myapp/myservice.svc/rest" 
      binding="webHttpBinding" 
      contract="MyProject.Contracts.IMyService" 
      name="IMyServiceRest"/> 

</client> 
</system.serviceModel> 

次に、あなたのコードでは、単に呼び出すことができます。

 ServiceHelper.UsingContract<"IMyServiceSoap", MyProject.Contracts.IMyService>(
      svc => svc.DoTheJob() 
      ); 

または

 ServiceHelper.UsingContract<"IMyServiceRest", MyProject.Contracts.IMyService>(
      svc => svc.DoTheJob() 
      ); 

[編集]サーバ設定は、この1のようになります。

<services> 
<service name="MyService"> 
    <endpoint address="soap" 
    binding="wsHttpBinding" 
         contract="MyContracts.IMyService"/> 
    <endpoint address="rest" 
    binding="webHttpBinding" 
         contract="MyContracts.IMyService"/> 
    <endpoint address="mex" 
         binding="mexHttpBinding" 
         contract="IMetadataExchange"/> 
</service> 
</services> 
+0

あなたのソープまたはjsonのシリアル化は私によって異なりますが、適切なシリアライゼーションタイプを選択するWCF機能を使用するには、リクエストのContentTypeに依存する – netmajor

+0

エンドポイント(およびそのバインド)単一エンドポイントのシリアル化の種類を変更する方法はありません。私は何かを見逃しているかもしれません、要求のコンテンツタイプを決定するのは何ですか?言い換えれば、石鹸のプロトコルまたは残りのプロトコルを使用する条件は何ですか? –

+0

私のサービスはasp.netページで呼び出され、Accept Type(application/jsonまたはapplication/soap + xml)に依存して適切なデータを返す必要があります。今のところ私はjsonを取得しますが、soapは失敗しました – netmajor

3

クライアント側に一つだけのエンドポイントが生成されるのはなぜ?

WCFは非SOAPエンドポイントのメタデータを出力しないためです。 SOAPのWSDLやMEXとは異なり、「REST」エンドポイントには広く使われているメタデータ形式はありません(WADLはその1つですが、WCFではそれほど使用されておらず実装されていません)ので、Add Service Reference(またはsvcutil) 1つのエンドポイントがメタデータ内に作成され、そのエンドポイントのみが作成されます。適切なシリアル化のタイプは、XML対要求

JSONのContentTypeを依存する選択私はWCFの機能を使用したい

シリアライゼーション・タイプの決定です。 JSONとSOAPは異なります(SOAPは、要求がどのように表示されるかについての規則を備えた、明確に定義されたプロトコルです)。WCF Dynamic Response Formatの詳細を参照してください。あなたのwebHttBinding -endpointは自動フォーマット選択を有効にしているので、JSONまたはXMLを受信リクエストに基づいて返しますが、このサービスを使用する方法はWCFクライアントである必要はありません。WebClientHttpWebRequestちょうどうまくいくはずです。

+0

ブラウザにサービスをテストするときにjsonエンドポイントをクライアントに追加しても、他の問題はhttp://service.renault.com/Service.svc/soap/GetSerializedDataまたはhttp:// serviceと入力しました.renault.com/Service.svc/json/GetSerializedData.Jsonの結果は、SOAPではなく、WCFトレースで返されました。「ネットワークから受信したXMLに問題があります。詳細は内部例外を参照してください。 > System.Xml.XmlException:空であるため、メッセージの本文を読み取れません " – netmajor

+1

ブラウザを使用して直接SOAPエンドポイントを呼び出すことはできません(つまり、アドレスバーにアドレスを入力する)。すべてのSOAP要求はHTTP POSTを介して行われ、ブラウザはバーに入力されたアドレスのGET要求を送信します。 – carlosfigueira

関連する問題