none
Can't change binding in Azure web role RRS feed

  • Question

  • When I create a WCF Service role, I cannot change the binding to wsHttpBinding.

    When I use the same web.config and just create a WCF service, it changes the binding just fine. Here is the contents of my web.config:

    <configuration>
      <system.web>
        <compilation debug="true" targetFramework="4.0"/>
      </system.web>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="ServiceBehavior">
              <serviceMetadata httpGetEnabled="True"/>
            </behavior>
            <behavior>
              <serviceMetadata httpGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
        <services>
          <service name="Service" behaviorConfiguration="ServiceBehavior">
            <endpoint address="" binding="wsHttpBinding" contract="IService1" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
          </service>
        </services>
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
        <directoryBrowse enabled="true"/>
      </system.webServer>
    </configuration>

    Here is the wsdl that is generated:

    <wsdl:binding name="BasicHttpBinding_IService1" type="tns:IService1">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="GetData">
    <soap:operation soapAction="http://tempuri.org/IService1/GetData" style="document"/>
    <wsdl:input>
    <soap:body use="literal"/>
    </wsdl:input>
    <wsdl:output>
    <soap:body use="literal"/>
    </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="GetDataUsingDataContract">
    <soap:operation soapAction="http://tempuri.org/IService1/GetDataUsingDataContract" style="document"/>
    <wsdl:input>
    <soap:body use="literal"/>
    </wsdl:input>
    <wsdl:output>
    <soap:body use="literal"/>
    </wsdl:output>
    </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="Service1">
    <wsdl:port name="BasicHttpBinding_IService1" binding="tns:BasicHttpBinding_IService1">
    <soap:address location="http://localhost:46934/Service1.svc"/>
    </wsdl:port>
    </wsdl:service>

    Which is the same as if I leave the default web.config. So maybe the web role is ignoring the web.config or is hard set to basicHttpBinding somewhere?

    David

    Wednesday, January 9, 2013 6:43 PM

Answers

  • I found the answer. You were right, I needed the namespace in the contract name.

    You can also force the application to not auto-create endpoints by inserting:

    <protocolMapping>
       <remove scheme="http"/>
       <remove scheme="https"/>
    </protocolMapping> 

    into the

    <system.serviceModel> 

    section

    Thanks.

    • Marked as answer by iamsdk Tuesday, January 29, 2013 4:40 PM
    Tuesday, January 29, 2013 4:40 PM

All replies

  • As a follow up, I renamed the service contract from IService1 to IService2 and indeed the wsdl was still generated with the new contract, so something is telling the compiler to ignore the web.config or something.
    Wednesday, January 9, 2013 6:46 PM
  • Hi,

    Try open the web.config file on the "WCF service configuration Editor" to edit the binding(find Endpoints, change the binding to wsHttpBinding) configuration and save.

    In addition, this link include an example using WsHttpBinding.

    http://msdn.microsoft.com/en-us/library/ms751418.aspx

    Best Regards.


    Haixia
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, January 11, 2013 3:19 AM
    Moderator
  • I did, it claimed the WCF service should be wsHttpBinding in contrast to what the service is--basicHttpBinding.
    Friday, January 11, 2013 4:05 AM
  • Hi,

    Do you save the changes? After modify and save changes, it will generate the new one in your config. In addition, you need specify the security mode for the wsHttpBinding binding. For example:

     <security mode="Transport">
                             <transport clientCredentialType="Digest"
                                proxyCredentialType="None"
                                realm="someRealm" />
                             <message clientCredentialType="Windows"
                                negotiateServiceCredential="false"
                                algorithmSuite="Aes128" 
                                defaultProtectionLevel="None" />
                        </security>
    Hope this helps.

    Best Regards.


    Haixia
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, January 11, 2013 11:15 AM
    Moderator
  • You don't need to specify the security mode.

    This thread is worthless.

    Friday, January 11, 2013 1:43 PM
  • Microsoft used to have the managed newsgroups as a first line support. Now the managed newsgroups are just tryying to outlast the issues presented.

    Microsoft is getting cheap with support.


    • Edited by iamsdk Saturday, January 12, 2013 4:38 AM
    Saturday, January 12, 2013 4:37 AM
  • Hi iamsdk,

    Hope that you are doing good today.

    Have you tried to collect WCF traces to see if actually the config file is being read or not? You need to add the following snippet under System.ServiceModel in the web.config file

    <diagnostics>
          <messageLogging logEntireMessage="true" logMalformedMessages="true"
            logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"
            maxSizeOfMessageToLog="26214445" />
        </diagnostics>

    And this snippet above System.ServiceModel:

    <system.diagnostics>

            <sources>
                <source name="System.ServiceModel.MessageLogging" switchValue="Verbose,ActivityTracing">
                    <listeners>
                        <add type="System.Diagnostics.DefaultTraceListener" name="Default">
                            <filter type="" />
                        </add>
                        <add name="ServiceModelMessageLoggingListener">
                            <filter type="" />
                        </add>
                    </listeners>
                </source>
                <source name="System.ServiceModel" switchValue="Information,ActivityTracing"
                    propagateActivity="true">
                    <listeners>
                        <add type="System.Diagnostics.DefaultTraceListener" name="Default">
                            <filter type="" />
                        </add>
                        <add name="ServiceModelTraceListener">
                            <filter type="" />
                        </add>
                    </listeners>
                </source>
            </sources>
            <sharedListeners>
                <add initializeData="C:\Traces\web_messages.svclog"  -- Please specify the path where you want the traces to be generated and give everyone full permission to it. 
                    type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                    name="ServiceModelMessageLoggingListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack">
                    <filter type="" />
                </add>
                <add initializeData="C:\Traces\web_tracelog.svclog"  -- Please specify the path where you want the traces to be generated and give everyone full permission to it. 
                    type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                    name="ServiceModelTraceListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack">
                    <filter type="" />
                </add>
            </sharedListeners>
        </system.diagnostics>

    Repro the issue and once you have the traces, in the traces find Initialize Service host activity which will tell you is if the config file is being read or not. 

    Also in the service tag you have defined the service name as only "Service". Can you use it as Namespace.Class name?

    Please make the above changes and collect the traces and let me know if it helps you out.

    Regards,

    Melissa-MSFT

    Monday, January 21, 2013 5:46 PM
  • So I am using the WCF test client and the ASP.Net development server as it is much easier to test.


    I made the changes you suggested but didn't see an activity for Initialize ServiceHost--I did, however see one for Open ServiceHost and there is an exception being thrown: System.ServiceModel.ProtocolException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

    With message: Content Type application/soap+xml; charset=utf-8 was sent to a service expecting text/xml; charset=utf-8.  The client and service bindings may be mismatched.

    I'm not sure if this is the client misreading something or an issue with the config file.

    David
    Monday, January 21, 2013 9:54 PM
  • Hi David,

    Thanks for testing this out. Can you paste the call stack that you see in the traces for this error? Also, it looks like some sort of binding mismatch at the client and the server end. Can you paste the config files for both the client and the server so that I can have a look at it? Also, just to confirm, when you took the traces, did you try with wsbinding or basichttpbinding? 

    Regards,

    Melissa - MSFT

    Tuesday, January 22, 2013 2:47 PM
  • Again, the web.config works fine in a normal WCF project. The Azure WCF Web Role is having the issue. 

    Stack trace:

    System.ServiceModel.Description.DispatcherBuilder.EnsureThereAreApplicationEndpoints(ServiceDescription description)
    System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost)
    System.ServiceModel.ServiceHostBase.InitializeRuntime()
    System.ServiceModel.ServiceHostBase.OnBeginOpen()
    System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
    System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
    System.ServiceModel.Channels.CommunicationObject.Open()
    System.ServiceModel.ServiceHostingEnvironment.HostingManager.ActivateService(ServiceActivationInfo serviceActivationInfo, EventTraceActivity eventTraceActivity)
    System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath, EventTraceActivity eventTraceActivity)
    System.ServiceModel.ServiceHostingEnvironment.EnsureServiceAvailableFast(String relativeVirtualPath, EventTraceActivity eventTraceActivity)
    System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
    System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
    System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
    System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
    System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
    System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

    Web.config (note, the WCF class is called Service1--I tried to add the namespace in addition to the class name as the name in the service node, but it threw an exception):

    <?xml version="1.0"?>
    <configuration>
      <system.web>
        <compilation debug="true" targetFramework="4.0"/>
      </system.web>
      <system.diagnostics>
            <sources>
                <source name="System.ServiceModel.MessageLogging" switchValue="Verbose,ActivityTracing">
                    <listeners>
                        <add type="System.Diagnostics.DefaultTraceListener" name="Default">
                            <filter type="" />
                        </add>
                        <add name="ServiceModelMessageLoggingListener">
                            <filter type="" />
                        </add>
                    </listeners>
                </source>
                <source name="System.ServiceModel" switchValue="Information,ActivityTracing"
                    propagateActivity="true">
                    <listeners>
                        <add type="System.Diagnostics.DefaultTraceListener" name="Default">
                            <filter type="" />
                        </add>
                        <add name="ServiceModelTraceListener">
                            <filter type="" />
                        </add>
                    </listeners>
                </source>
            </sources>
            <sharedListeners>
                <add initializeData="C:\web_messages.svclog"   
                    type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                    name="ServiceModelMessageLoggingListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack">
                    <filter type="" />
                </add>
                <add initializeData="C:\web_tracelog.svclog"   
                    type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                    name="ServiceModelTraceListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack">
                    <filter type="" />
                </add>
            </sharedListeners>
        </system.diagnostics>

      <system.serviceModel>
        
        <diagnostics>
          <messageLogging logEntireMessage="true" logMalformedMessages="true"
            logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"
            maxSizeOfMessageToLog="26214445" />
        </diagnostics>
        <behaviors>
          <serviceBehaviors>
            <behavior name="ServiceBehavior">
              <serviceMetadata httpGetEnabled="True"/>
            </behavior>
            <behavior>
              <serviceMetadata httpGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
        <services>
          <service name="Service1" behaviorConfiguration="ServiceBehavior">
            <endpoint address="" binding="wsHttpBinding" contract="IService1" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
          </service>      
        </services>
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
        <directoryBrowse enabled="true"/>
      </system.webServer>
    </configuration>

    Client config (from the WCF Test Client):

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
        <system.serviceModel>
            <bindings>
                <basicHttpBinding>
                    <binding name="BasicHttpBinding_IService1" sendTimeout="00:05:00" />
                </basicHttpBinding>
            </bindings>
            <client>
                <endpoint address="http://localhost:46934/Service1.svc" binding="basicHttpBinding"
                    bindingConfiguration="BasicHttpBinding_IService1" contract="IService1"
                    name="BasicHttpBinding_IService1" />
            </client>
        </system.serviceModel>
    </configuration>

    Thanks,

    David

    Tuesday, January 22, 2013 4:49 PM
  • I found the answer. You were right, I needed the namespace in the contract name.

    You can also force the application to not auto-create endpoints by inserting:

    <protocolMapping>
       <remove scheme="http"/>
       <remove scheme="https"/>
    </protocolMapping> 

    into the

    <system.serviceModel> 

    section

    Thanks.

    • Marked as answer by iamsdk Tuesday, January 29, 2013 4:40 PM
    Tuesday, January 29, 2013 4:40 PM