I'd like to remove the Expect: 100-continue header that is added by the underlying HttpWebRequest used in basicHttpBinding. I am aware of the option to simply set ServicePointManager.Expect100Continue to false. However, the problem with this approach is that it is global, i.e. it applies to all web requests initiated in the process. I would like to limit the scope of this to a specific WCF proxy. With an ASMX proxy this used to be easy - I would simply subclass the generated proxy which is a subclass of SoapHttpClientProtocol and override GetWebRequest. I would then call the base implementation and set the Expect100Continue on the returned web request object.
I am trying to apply a similar approach with WCF but can't quite find a method to "intercept" the HttpWebRequest created by the transport channel. Is this possible?
For System.ServiceModel.Http
4.5, we can create a custom BasicHttpBinding
injecting a HttpMessageHandler
in the HttpClient
pipeline:
class CustomHttpBinding: BasicHttpBinding
{
public override BindingElementCollection CreateBindingElements()
{
var elements = base.CreateBindingElements();
var transport = elements.Find<HttpsTransportBindingElement>();
if (transport != null)
{
elements.Remove(transport);
elements.Add(CustomHttpsTransportBindingElement.CreateFromHttpsTransportBindingElement(transport));
}
return elements;
}
}
class CustomHttpsTransportBindingElement: HttpsTransportBindingElement
{
private Func<HttpClientHandler, HttpMessageHandler> _createDelegatingHandler = client => new CustomHttpMessageHandler(client);
public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
{
context.BindingParameters.Add(_createDelegatingHandler);
return base.BuildChannelFactory<TChannel>(context);
}
public override BindingElement Clone()
{
return CreateFromHttpsTransportBindingElement(this);
}
public static CustomHttpsTransportBindingElement CreateFromHttpsTransportBindingElement(HttpsTransportBindingElement from)
{
return new CustomHttpsTransportBindingElement
{
AllowCookies = from.AllowCookies,
AuthenticationScheme = from.AuthenticationScheme,
BypassProxyOnLocal = from.BypassProxyOnLocal,
ManualAddressing = from.ManualAddressing,
MaxBufferSize = from.MaxBufferSize,
MaxReceivedMessageSize = from.MaxReceivedMessageSize,
ProxyAddress = from.ProxyAddress,
ProxyAuthenticationScheme = from.ProxyAuthenticationScheme,
RequireClientCertificate = from.RequireClientCertificate,
TransferMode = from.TransferMode,
UseDefaultWebProxy = from.UseDefaultWebProxy,
WebSocketSettings = from.WebSocketSettings
};
}
}
class CustomHttpMessageHandler: DelegatingHandler
{
public CustomHttpMessageHandler(HttpMessageHandler innerHandler): base(innerHandler)
{
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.ExpectContinue = false;
return base.SendAsync(request, cancellationToken);
}
}
If you are not on HTTPS, override HttpTransportBindingElement
instead of HttpsTransportBindingElement
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With