开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜