Search code examples
c#protocolsprotocol-buffersapp-configservicecontract

WCF service with protocol buffer, how the config file will look like


I worked on WCF before. But I am very new in protocol buffers. I went through its advantages and how to use it. Basically i want to plug in the protocol buffers into my existing 'WCF library'. So what changes should i make in my existing 'app.config' file to introduce or start working with protocol buffers? My existing service Config file is as follows.

<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
    <add key="ClientSettingsProvider.ServiceUri" value="" />
  </appSettings>
  <system.web>
    <compilation debug="true" />
    <membership defaultProvider="XYZProvider">
      <providers>
        <add name="XYZshipProvider" type="System.Web.ClientServices.Providers.XYZProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf35678563123ad364e35" serviceUri="" />
      </providers>
    </membership>
    <roleManager defaultProvider="ClientRoleProvider" enabled="true">
      <providers>
        <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856564ad364e35" serviceUri="" cacheTimeout="86400" />
      </providers>
    </roleManager>
  </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="wcfServiceXYZApplication.Service1">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/Design_Time_Addresses/XYZApplication/Service1/" />
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint address="" binding="basicHttpBinding" contract="XYZApplication.IService1" bindingConfiguration="basicHttp">
          <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <!-- Metadata Endpoints -->
        <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
        <!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
          <!-- 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>
  <bindings>
    <basicHttpBinding>
      <binding name="basicHttp" maxReceivedMessageSize="100000" maxBufferSize="100000" maxBufferPoolSize="100000"/>
    </basicHttpBinding>
  </bindings>
  </system.serviceModel>

</configuration>

Please help! Thanks


Solution

  • Here is the modifications i did in config for the service side

    <configuration>
      <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
        <add key="ClientSettingsProvider.ServiceUri" value="" />
      </appSettings>
      <system.web>
        <compilation debug="true" />
        <membership defaultProvider="XYZProvider">
          <providers>
            <add name="XYZshipProvider" type="System.Web.ClientServices.Providers.XYZProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf35678563123ad364e35" serviceUri="" />
          </providers>
        </membership>
        <roleManager defaultProvider="ClientRoleProvider" enabled="true">
          <providers>
            <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856564ad364e35" serviceUri="" cacheTimeout="86400" />
          </providers>
        </roleManager>
      </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>
    <behaviors>
      <endpointBehaviors>
        <behavior name="protoEndpointBehavior">
          <protobuf/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    
    <bindings>
      <netNamedPipeBinding>
        <binding name="namedPipeBinding" receiveTimeout="00:10:00" sendTimeout="0:10:00" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" />
      </netNamedPipeBinding>
    </bindings>
    
    <services>
      <service name="WcfProtobufService.SimpleService">
        <endpoint binding="netNamedPipeBinding" bindingConfiguration="namedPipeBinding" contract="WcfProtobufService.ISimpleService" behaviorConfiguration="protoEndpointBehavior"/>
        <endpoint address="mex" binding="mexNamedPipeBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="net.pipe://localhost/console/SimpleService.svc"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    
    <extensions>
      <behaviorExtensions>
        <add name="protobuf" type="ProtoBuf.ServiceModel.ProtoBehaviorExtension, protobuf-net, Version=2.0.0.668, Culture=neutral, PublicKeyToken=257b51d87d2e4d67"/>
      </behaviorExtensions>
    </extensions>
    


    along with this i changed client side config file too...Just change system.serviceModel section as follows

    <system.serviceModel>
        <behaviors>
          <endpointBehaviors>
            <behavior name="protoEndpointBehavior">
              <protobuf/>
            </behavior>
          </endpointBehaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
    
        <bindings>
          <netNamedPipeBinding>
            <binding name="NetNamedPipeBinding_ISimpleService" receiveTimeout="00:10:00" sendTimeout="0:10:00" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" />
          </netNamedPipeBinding>
        </bindings>
        <client>
          <endpoint address="net.pipe://localhost/console/SimpleService.svc"
              binding="netNamedPipeBinding" bindingConfiguration="NetNamedPipeBinding_ISimpleService"
              contract="SimpleProxy.ISimpleService" name="NetNamedPipeBinding_ISimpleService" behaviorConfiguration="protoEndpointBehavior">
          </endpoint>
        </client>
    
        <extensions>
          <behaviorExtensions>
            <add name="protobuf" type="ProtoBuf.ServiceModel.ProtoBehaviorExtension, protobuf-net, Version=2.0.0.668, Culture=neutral, PublicKeyToken=257b51d87d2e4d67"/>
          </behaviorExtensions>
        </extensions>
      </system.serviceModel>
    

    Also To enable protobuf serialization for your WCF Data Contracts, first you need to

    1. add the [ProtoContract] attribute to every DTO (Data Transfer Object) that needs the [DataContract] attribute and the [ServiceContract] attribute..
    2. add the [ProtoMember] attribute to every DTO data field that needs the [DataMember] attribute.

      changes for IService

          [ProtoMember(2)]
          [DataMember(Order = 0)]
          public string Name { get; set; }
      

      changes for service- just add Protocontract attribute over the service contract

      [ProtoContract]
      [ServiceContract]

    Last but not least add

    using ProtoBuf
    

    Refered ...

    https://whinery.wordpress.com/2014/10/28/wcf-with-protobuf-serialization/