WCF 新手:创建 WCF 代理以连接到旧的 ASMX Web 服务

发布于 2024-10-17 15:27:09 字数 3070 浏览 1 评论 0原文

我当前分配的任务是,我需要创建一个 WCF,该 WCF 将充当 3 个 ASMX 服务的代理。目前,这些服务由多个应用程序直接使用。

构建此 WCF 代理的原因是,我们可以更轻松地在一个入口点(WCF 代理服务)而不是多个应用程序中更新 asmx 证书。

我创建了一个普通的 .NET 类库,它基本上为 ASMX 服务创建一个单例实例,但我不确定如何在 WCF 服务中公开它。

如果您能指出我在哪里可以看到 WCF 充当消费 ASMX 服务代理的示例,是否有可能?

下面是我的代码:

public static class Service<T> where T : WebServicesClientProtocol
{
    static volatile T _Instance;
    static volatile int _NumberOfReference = 0;
    static object syncRoot = new object();

    static Service() { }

    public static T Instance
    {
        get
        {
            if (_Instance == null)
            {
                lock (syncRoot)
                {
                    if (_Instance == null)
                    _Instance = ServiceProxyHelper.CreateServiceProxy<T>(ConfigValueHelper.GetServiceUrl(typeof(T).Name), ConfigValueHelper.CertificateHashKey);
                }
            }
            return _Instance;
        }
    }
}

这是我使用的助手:

public static class ServiceProxyHelper
{
    public static T CreateServiceProxy<T>(string url, string clientBase64KeyId)
    {
        var webService = SetSecurityCredentials(clientBase64KeyId, url, typeof(T));

        if (webService == null)
            return default(T);

        return (T)Convert.ChangeType(webService, typeof(T));
    }

    private static WebServicesClientProtocol SetSecurityCredentials(string clientBase64KeyId, string url, Type serviceType)
    {
        WebServicesClientProtocol result = null;

        result = (WebServicesClientProtocol)Activator.CreateInstance(serviceType, true);
        result.Url = url;

        //Verify default credentials
        if (WebRequest.DefaultWebProxy != null)
        {
            result.Proxy = WebRequest.DefaultWebProxy;
            result.Credentials = CredentialCache.DefaultCredentials;
            result.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
        }

        //Add security credentials to SOAP envelope
        var token = ServiceProxyHelper.GetSecurityToken(clientBase64KeyId, url);

        if (token == null)
            return null;

        result.RequestSoapContext.Security.Tokens.Add(token);
        result.RequestSoapContext.Security.Elements.Add(new MessageSignature(token));

        return result;
    }

    private static X509SecurityToken GetSecurityToken(string clientBase64KeyId, string url)
    {
        X509SecurityToken result = null;
        X509Certificate x509Certificate = null;

        var store = X509CertificateStore.CurrentUserStore(X509CertificateStore.MyStore);
        var isOpen = store.OpenRead();

        foreach (X509Certificate certificate in store.Certificates)
        {
            if (Convert.ToBase64String(certificate.GetKeyIdentifier()) != clientBase64KeyId)
                continue;

            x509Certificate = certificate;
            result = new X509SecurityToken(certificate);
            break;
        }

        if (isOpen)
            store.Close();

        return result;
    }
}

I am currently assigned on a task where I need to create a WCF that will act as a proxy to 3 ASMX services. Currently these services are consumed directly by several applications.

Reason for building this WCF proxy is that it would be easier for us to update the asmx certificates in just one point of entry (the WCF proxy service) rather than several applications.

I've created an ordinary .NET class library that basically creates a singleton instance for the ASMX service, but I'm not sure how I could expose it in a WCF service.

Would it be possible if you could point me out where I could see excamples of a WCF acting as a proxy for consuming ASMX services?

Below is my code:

public static class Service<T> where T : WebServicesClientProtocol
{
    static volatile T _Instance;
    static volatile int _NumberOfReference = 0;
    static object syncRoot = new object();

    static Service() { }

    public static T Instance
    {
        get
        {
            if (_Instance == null)
            {
                lock (syncRoot)
                {
                    if (_Instance == null)
                    _Instance = ServiceProxyHelper.CreateServiceProxy<T>(ConfigValueHelper.GetServiceUrl(typeof(T).Name), ConfigValueHelper.CertificateHashKey);
                }
            }
            return _Instance;
        }
    }
}

And this is the helpers that I use:

public static class ServiceProxyHelper
{
    public static T CreateServiceProxy<T>(string url, string clientBase64KeyId)
    {
        var webService = SetSecurityCredentials(clientBase64KeyId, url, typeof(T));

        if (webService == null)
            return default(T);

        return (T)Convert.ChangeType(webService, typeof(T));
    }

    private static WebServicesClientProtocol SetSecurityCredentials(string clientBase64KeyId, string url, Type serviceType)
    {
        WebServicesClientProtocol result = null;

        result = (WebServicesClientProtocol)Activator.CreateInstance(serviceType, true);
        result.Url = url;

        //Verify default credentials
        if (WebRequest.DefaultWebProxy != null)
        {
            result.Proxy = WebRequest.DefaultWebProxy;
            result.Credentials = CredentialCache.DefaultCredentials;
            result.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials;
        }

        //Add security credentials to SOAP envelope
        var token = ServiceProxyHelper.GetSecurityToken(clientBase64KeyId, url);

        if (token == null)
            return null;

        result.RequestSoapContext.Security.Tokens.Add(token);
        result.RequestSoapContext.Security.Elements.Add(new MessageSignature(token));

        return result;
    }

    private static X509SecurityToken GetSecurityToken(string clientBase64KeyId, string url)
    {
        X509SecurityToken result = null;
        X509Certificate x509Certificate = null;

        var store = X509CertificateStore.CurrentUserStore(X509CertificateStore.MyStore);
        var isOpen = store.OpenRead();

        foreach (X509Certificate certificate in store.Certificates)
        {
            if (Convert.ToBase64String(certificate.GetKeyIdentifier()) != clientBase64KeyId)
                continue;

            x509Certificate = certificate;
            result = new X509SecurityToken(certificate);
            break;
        }

        if (isOpen)
            store.Close();

        return result;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

久夏青 2024-10-24 15:27:09

在这种情况下,我将在 WCF 中创建一个 [ServiceContract] 并添加我希望客户端访问的 ASMX 中的所有方法。然后使用 WCF 端点公开该服务协定。它就像一个门面。希望这对您有意义。

I this case i would create a [ServiceContract] in WCF and add all the methods from ASMX that i want the clients to access. Then expose that service contract using WCF endpoints. It would act like a facade. Hope this makes sense to you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文