How to programatically set a single endpoint for a WCF service

别来无恙 提交于 2019-12-22 08:47:00

问题


I'm trying to allow for user configuration of a WCF service, including the IP and port number that the service listens on. The user has a separate config application that allows for these values to be set, but the problem I am running into is that the app.config MUST have an endpoint defined in order to create a new ServiceHost entry...but my endpoint is being defined in a separate configuration file and must then be bound programatically at runtime.

If I do the following (based on How to programatically modify WCF app.config endpoint address setting?:

        m_SvcHost = new ServiceHost(this);

        if (Config.ServiceEndpoint != null && Config.ServiceEndpoint != String.Empty)
        {
            m_SvcHost.AddServiceEndpoint(typeof(IMyService),
                new BasicHttpBinding(),
                Config.ServiceEndpoint);
        }

        m_SvcHost.Open();

the service will listen on BOTH the URI defined in the app.config, AND the URI defined in the configuration file. There is no way that I can find to remove the original endpoint or to create the service without an endpoint defined.

Writing to the app.config from the configuration application is not an option - I need to pull the configured value programatically from the separate XML config file....

any thoughts?

EDIT: the service runs as a Windows Service and exposes an HTTP endpoint, it is not running as a web service hosted in IIS - if that changes things at all


回答1:


Justin,

Does this help you? This code will allow you to respond to any address that you list in the CreateServiceHost() method.

public class CRSyncServiceHost : ServiceHost
{
    public CRSyncServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses) { }

    protected override void ApplyConfiguration()
    {
        base.ApplyConfiguration();
    }
}

public class CRSyncServiceFactory : ServiceHostFactory
{
    protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        Uri newServiceAddress = new Uri("http://someaddress.com/CRSyncService.svc");
        CRSyncServiceHost newHost = new CRSyncServiceHost(serviceType, newServiceAddress);
        return newHost;
    }
}

<%@ ServiceHost Language="C#" Debug="true" Service="CRSyncService" Factory="CRSyncServiceFactory" CodeBehind="CRSyncService.svc.cs" %>



回答2:


Well I don't have tremendous WCF background, but would this work?

m_SvcHost = new ServiceHost(this);
m_SvcHost.Description.Endpoints.Clear(); // <-- added

if (Config.ServiceEndpoint != null && Config.ServiceEndpoint != String.Empty)
{
    m_SvcHost.AddServiceEndpoint(typeof(IMyService),
        new BasicHttpBinding(),
        Config.ServiceEndpoint);
}

m_SvcHost.Open();



回答3:


By combining both gWiz and Dylan's answers I came up with a way to do this, though I haven't tested thoroughly enough to know if I have broken any other functionality with these changes.

Basically, I added this class:

public class MobileMonitoringSvcHost : ServiceHost
{
    protected override void ApplyConfiguration()
    {
        // skip this line to not apply default config - unsure of other ramifications of doing this yet...
        base.ApplyConfiguration();

        base.Description.Endpoints.Clear();
    }

    public MobileMonitoringSvcHost(object singletonInstance, params Uri[] baseAddresses) : base(singletonInstance, baseAddresses)
    {

    }
}

This skips the ServiceHost "ApplyConfiguration" call and (likely needlessly for now because if the config isn't loaded there should be no endpoints) clears the endpoints. Then I do the following:

m_SvcHost = new MySvcHost(this);


        if (Config.ServiceEndpoint != null && Config.ServiceEndpoint != String.Empty)
        {
            //m_SvcHost.Description.Endpoints.Clear();


            m_SvcHost.AddServiceEndpoint(typeof(IMobileMonitoringSvc),
                new BasicHttpBinding(),
                Config.ServiceEndpoint);
        }


        // open the svchost and allow incoming connections
        m_SvcHost.Open();

This does cause the service to only listen on the externally configured endpoint and not the app.config configured endpoint

Thanks!




回答4:


You don't have to have the configuration piece at all, I don't believe - i.e. you can do it all in code. If you leave the stuff in .config then it'll be used along with what you write in code.

If you want one or the other, I think you have to remove one or the other.



来源:https://stackoverflow.com/questions/2059485/how-to-programatically-set-a-single-endpoint-for-a-wcf-service

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!