1
votes

I have a thick client which opens channels on several WCF services. The services are built using C#, WCF, nHibernate, Fluent and Unity (ServiceHostFactory).

When I try to access the MetaData for Plate.svc through the browser I get a 400 bad request which generates no log statements although the good requests from the app do. All requests from the app work normally.

Any ideas?

I've included the important bits of the following files:

  1. Service markup
  2. Service Contract
  3. Service Web.config
  4. Client App.config

1. Service Markup

ServiceHost Language="C#" Debug="true" Service="PRO.Services.PlateService" CodeBehind="Plate.svc.cs" Factory="PRO.Services.Configuration.UnityServiceHostFactory"

2. Service Contract

namespace PRO.ServiceContracts {
    [ServiceContract]
    public interface IPlateService {
        [OperationContract]
        [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        [FaultContract(typeof(string))]
        AnalysisPlate Search(string barcode);

        // identically defined operations removed
    }
}

3. Service Web.config

   <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpEndpointBinding">
          <security mode="None">
            <transport clientCredentialType="None" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ProBehavior">
          <serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
    <services>
      <service behaviorConfiguration="ProBehavior" name="PRO.Services.PlateService">
        <endpoint address="" contract="PRO.ServiceContracts.IPlateService"
                  binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpointBinding"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
      <service behaviorConfiguration="ProBehavior" name="PRO.Services.SampleService">
        <endpoint address="" contract="PRO.ServiceContracts.ISampleService" 
                  binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpointBinding"/>
      </service>
    </services>
   </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
    </modules>
  </system.webServer>

4. Client App.config

 <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_Normal">
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:4829/Sample.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_Normal" contract="PRO.ServiceContracts.ISampleService" name="DEV_ISampleService" />
      <endpoint address="http://localhost:4829/Plate.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_Normal" contract="PRO.ServiceContracts.IPlateService" name="DEV_IPlateService" />
    </client>
  </system.serviceModel>
1
I'm not sure this is the source of your problem, but have you noticed that you're using slightly different bindings on the client and the server. The server is set to SecurityMode="None" but the client is set to "TransportCredentialOnly." Is there a reason for this?Paul Wheeler
Also I find enabling WCF Service Tracing and using the Service Trace Viewer to be infinitely useful when debugging such issues. See this article for details: msdn.microsoft.com/en-us/library/ms733025.aspxPaul Wheeler
1. That shouldn't be a problem with MetaData since the client definition will not be used in that case.Lorenzo
2. Should WCF Service Tracing be helpful when trying to access the MetaData through the browser? I ask because I've got it turned on in my development server and the only statements I see are from client data requests. Nothing from MetaData requests.Lorenzo
I found that I have two logs! Attempt to access the service/mex from the browser throws the exception "The body of the message cannot be read because it is empty." Which I thought would not happen if I enabled the get.Lorenzo

1 Answers

1
votes

Turns out the problem was related to using a factory Factory="PRO.Services.Configuration.UnityServiceHostFactory"

There are two things about this that haven't been well documented:

1) Use a ServiceHost in conjunction with your factory (not a WebServiceHost) 2) You will probably need to setup your MetaData endpoints in the custom service host as detailed in this post by Microsoft: http://msdn.microsoft.com/en-us/library/aa395224.aspx