46

I've got a hosted WCF service that I created a custom factory for, so that this would work with multiple host headers:

/// <summary>
/// Required for hosting where multiple host headers are present
/// </summary>
public class MultipleHostServiceFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        List<Uri> addresses = new List<Uri>();
        addresses.Add(baseAddresses[0]);
        return base.CreateServiceHost(serviceType, addresses.ToArray());
    }
}

I'm pretty sure that my config files are now right, on both client and server (can be seen here).

The error I'm getting appears to be related to the factory:

Manual addressing is enabled on this factory, so all messages sent must be pre-addressed.

public string GetData(int value) {
    return base.Channel.GetData(value);
}

The error occurs at line return base.Channel.GetData(value);.

Ivar
  • 6,138
  • 12
  • 49
  • 61
ElHaix
  • 12,846
  • 27
  • 115
  • 203

4 Answers4

65

I experienced this error and the problem was resolved by adding the WebHttpBehavior (line 2 below):

var factory = new ChannelFactory<IService>(new WebHttpBinding(), uri);
factory.Endpoint.Behaviors.Add(new WebHttpBehavior());
var proxy = factory.CreateChannel();
bendewey
  • 39,709
  • 13
  • 100
  • 125
  • 3
    The answers above did not help at all. But your solution worked. Thanks. – Matthias Aug 02 '13 at 11:02
  • 1
    If the endpoint has specified, you need to use WebScriptEnablingBehavior instead, otherwise you'll always get "Faulted status". – Stefan Steiger Oct 13 '14 at 11:32
  • 1
    This worked for me but I also had to add a using reference for WebHttpBehavior -> `using System.ServiceModel.Description;` – Ian Newland Dec 06 '15 at 15:30
  • For those like me, who copy/pasted without thinking, you have to use actually have to use/inject the "*proxy*" object (of type *IService* in the above), into your code if you want this configuration to take effect. – ryanwebjackson Nov 08 '17 at 21:02
31

I added a service reference as usual and got this error. Turns out all I had to do was to amend the client config to use an endpoint config with a behaviour specifing webhttp

<client>
  <endpoint address="http://localhost:9000/GeoConverterService/GeoConverterService.svc"
            binding="webHttpBinding" 
            contract="GeoConverter.IGeoConverterService" 
            behaviorConfiguration="webhttp"/>
</client>

<behaviors>
  <endpointBehaviors>
    <behavior name="webhttp">
      <webHttp/>
    </behavior>
  </endpointBehaviors>
</behaviors>

JiBéDoublevé
  • 4,124
  • 4
  • 36
  • 57
jason mardell
  • 319
  • 3
  • 2
2

I don't think this necessarily has anything to do with your factory.

See

http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.transportbindingelement.manualaddressing.aspx

or others among the first few Bing hits for "manualaddressing". It sounds like the binding being used is incompatible with some other portion of the stack/messaging logic.

Brian
  • 117,631
  • 17
  • 236
  • 300
  • Well, I'm not using custom biding - using web webHttpBinding - defined in both. Initially a problem was that the client only had custom binding defined (I simply made a service reference to my WCF server and let VS do the rest). Still looking into this new error... – ElHaix Nov 25 '09 at 17:27
  • 'add service reference' and 'webHttpBinding' don't work together well, and would explain the error. I think your client is trying to talk SOAP using a WS-Addressing binding to your REST-y service that just speaks HTTP. – Brian Nov 25 '09 at 17:38
  • So using svcutil.exe to create my WCF client would be a better route? – ElHaix Nov 25 '09 at 18:25
  • No; if you are using webHttpBinding, then neither svcutil nor add service reference are good. You either want to hand-code the client (share contract types etc) or use a 'generic' http client that just speaks the universal REST/CRUD interface. – Brian Nov 25 '09 at 18:44
  • Yeah, I realize that - just generated the proxy class, re-config'ed it all and getting the same error. Ok, so since I'm going through HTTPS do I have to use webHttpBinding? I just need to get a basic service up and running on this host so we can leap off from there. – ElHaix Nov 25 '09 at 19:21
  • You don't have to use webHttp to get https, you can use basicHttp/wsHttp and do https, the axis here is REST v SOAP (web v basic/ws) – Brian Nov 25 '09 at 20:07
  • I've also tried switching back to the customBinding, where I added httpTransport manualAddressing="false" - and now getting "The remote server returned an error: (405) Method Not Allowed. As per your recommendation I switched it all to use wsHttpBinding and I'm still getting the same 405 error. – ElHaix Nov 25 '09 at 21:59
  • If you are getting a 405, this means the server and client bindings are mismatched (one is using webHttp and thus the GET method, and one is using wsHttp and thus the POST method). – Brian Nov 25 '09 at 22:18
2

So this has finally come to an end!

Brian - thanks for your guidance on this. The bindings were mis-aligned b/t the client and server, and I finally ended up going with the following in both:

  <basicHttpBinding>
    <binding name="TransportSecurity">
      <security mode="Transport">
        <transport clientCredentialType="None"/>
      </security>
    </binding>
  </basicHttpBinding> 

... and setting their endpoint binding and bindingConfiguration attributes accordingly:

   <endpoint binding="basicHttpBinding" 
             bindingConfiguration="TransportSecurity"
             contract="ServiceReference1.IService" 
             name="WebHttpBinding_IService" 
             address="https://mysslserver.com/Service.svc" />

Since this is relatively new turf for me, just the explanation of why those errors were popping up lead me in the right direction :).

JiBéDoublevé
  • 4,124
  • 4
  • 36
  • 57
ElHaix
  • 12,846
  • 27
  • 115
  • 203