Add a Binding Extension via Code
I'm trying to figure out a way to add a binding extension to an endpoint via code, instead of through configuration files. Ideally I want it to simply be an attr开发者_StackOverflow社区ibute I place on the service method.
So far it seems like the only thing that isn't exposed publicly is the binding extensions.
If you give me some more context I can rewrite using your code pieces. Just let me know the names of your binding extensions....
If you need to use WebServiceHostFactory
public class ServiceHostFactory : WebServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
ServiceHost serviceHost = new ServiceHost(typeof(IService));
CustomBinding customBinding= new CustomBinding();
customBinding.Name = “myCustomBinding”;
customBinding.Elements.Add(new SomeBindingExtensionElement());
serviceHost.AddServiceEndpoint(typeof(IService), customBinding,
“http://localhost/service/CustomEndpoint”);
So I figured it out, I had to first subclass WebServiceHostFactory:
/// <summary>
/// RestServiceFactory extends WebServiceHostFactory and adds support for JSONP encoding
/// </summary>
public class RestServiceFactory : WebServiceHostFactory
{
/// <summary>
/// Creates a ServiceHost using the first address in baseAddresses
/// </summary>
/// <param name="serviceType"></param>
/// <param name="baseAddresses"></param>
/// <returns></returns>
protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
Uri[] defaultAddresses = new Uri[1];
defaultAddresses[0] = baseAddresses[0];
ServiceHost host = new RestServiceHost(serviceType, defaultAddresses);
// Bind up the JSONP extension
CustomBinding cb = new CustomBinding(new WebHttpBinding());
cb.Name = "JSONPBinding";
// Replace the current MessageEncodingBindingElement with the JSONP element
var currentEncoder = cb.Elements.Find<MessageEncodingBindingElement>();
if (currentEncoder != default(MessageEncodingBindingElement))
{
cb.Elements.Remove(currentEncoder);
cb.Elements.Insert(0, new JSONP.JSONPBindingElement());
}
host.AddServiceEndpoint(serviceType.GetInterfaces()[0], cb, defaultAddresses[0]);
return host;
}
}
And then I had to subclass WebServiceHost to modify how it was setting up behaviors:
/// <summary>
/// RestServiceHost extends WebServiceHost to add JSONP support
/// </summary>
public class RestServiceHost : WebServiceHost
{
public RestServiceHost() : base() { }
public RestServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType,baseAddresses) { }
protected override void OnOpening()
{
base.OnOpening();
if (base.Description != null)
{
foreach (ServiceEndpoint endpoint in base.Description.Endpoints)
{
if ((endpoint.Binding != null) && (endpoint.Binding.CreateBindingElements().Find<JSONP.JSONPBindingElement>() != null))
{
if (endpoint.Behaviors.Find<WebHttpBehavior>() == null)
{
endpoint.Behaviors.Add(new WebHttpBehavior());
}
}
}
}
}
}
The reason for this change is because WebServiceHost was not adding any behaviors because of the custom binding.
With these two changes done, the requests were piped through the correct binding extension, no web.config changes needed.
精彩评论