【问题标题】:WCF Newbie: Create a WCF Proxy to connect to old ASMX Web ServiceWCF 新手:创建 WCF 代理以连接到旧的 ASMX Web 服务
【发布时间】:2011-02-15 15:40:40
【问题描述】:

我目前被分配了一项任务,我需要创建一个 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;
    }
}

【问题讨论】:

  • 您无法更改现有的 asmx 服务吗?为什么需要代理与将服务更新到 WCF ?另外 - 你为什么认为你需要一个单例实例?
  • @markt:我正在使用第 3 方 asmx 网络服务,所以我们无法控制它。目前,我们的应用程序在直接使用 asmx 时使用的是单例实例,所以我错误地认为它与 WFC 相同。我们需要代理来进行维护,因为第 3 方 asmx 使用 SSL 证书,并且每年我们都必须更新所有使用它的应用程序。更新所有使用它的应用程序对我们来说会很乏味。
  • 好的 - 你提到你有 3 个服务。我建议不要为所有服务使用具有方法的单个代理。这有点像上帝服务,如果您需要为每个服务设置不同的访问规则,以后可能会导致问题...除非所有 3 个服务都 总是被所有客户使用。如果您必须逐步淘汰其中一个怎么办..您想为所有客户打破合同吗?您可以在单个应用程序中托管多个服务代理端点,或者依靠一个通用配置文件来解决您的维护问题。

标签: c# .net wcf asmx soa


【解决方案1】:

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

【讨论】:

  • 感谢这个阿卜杜勒。追问:我还需要为asmx服务返回的数据指定DataContract属性吗?
  • @mallows98:是的;如果您使用 WCF,则需要编写客户端代理,就好像您正在与 WCF 服务交互一样 - WCF 客户端代理不知道也不关心该服务是一个 ASMX。为 WCF 服务创建 WCF 客户端的所有内容也适用于此。
  • 感谢马克和阿卜杜勒!非常感谢您的反馈!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多