调用WebServices的通用方法

时间:2017-05-09 12:10:47

标签: c# generics

我正在尝试创建一个方法来控制从前端到后端的调用。 为此,我已经编写了一个通用方法(因为我有很多SoapClients)

public static TRet CallWebServiceAndReturn<TRet, TClient>(ClientBase<TClient> client, string methodName, object[] parameters, bool cacheThis) 
        where TClient : ClientBase<TClient>
    {
        //seta retorno para null como default
        object ret = null;

        //recupera Type da classe
        Type clientType = typeof(TClient);

        //recupera método da classe para ser executado
        MethodInfo method = clientType.GetMethod(methodName);

        //cache
        if (cacheThis)
        {
            string cacheKey = CacheManager.GenerateCacheKey(clientType.Name, method.Name, parameters);
            if (CacheManager.TryGetFromCacheWS(cacheKey, out ret))
                return (TRet)ret;
        }

        try
        {
            //tenta executar o método
            ret =   method.Invoke(client, parameters);
        }
        catch (Exception)
        {
            //em caso de erro, fecha conexões
            if (client.State == CommunicationState.Faulted)
                client.Abort();
            else
                client.Close();
        }

        //se cache está habilitado, faaz o cache do resultado da chamada
        if (cacheThis)
        {
            string cacheKey = CacheManager.GenerateCacheKey(clientType.Name, method.Name, parameters);
            CacheManager.AddToCacheWS(cacheKey, ret);
        }

        //converte retorno em RET e retorna
        return (TRet)ret;
    }

我不知道通用TClient必须是什么样的。 当我从Visual Studio检查自动生成的客户端时,它扩展了一个ClientBase,因此,我得出结论,我只需要把它放在“where”clausule中:

 where TClient : ClientBase<TClient>

自动生成的SoapClient实现:

 public partial class MenuSoapClient : System.ServiceModel.ClientBase<frontend.WSMenu.MenuSoap>, frontend.WSMenu.MenuSoap {

此时,我没有任何错误,但是,我尝试编写一些代码:

 public static CategoryType[] GetSuperiorMenu(int idUser, int idRegion, int idRole, int idLanguage)
    {
        object[] parameters = new object[] { idUser, idRegion, idRole, idLanguage };

        CategoryType[] ret = null;

        MenuSoapClient menuClient = new MenuSoapClient();
        ret = WSClientService.CallWebServiceAndReturn<CategoryType[], MenuSoapClient>(menuClient, "GetSuperiorMenu", parameters, true);
//rest of my code

在最后一行中,Visual Studio在“menuClient”上给出了一个错误,第一个参数:

无法从frontend.WSMenu.MenuSoapClient转换为System.ServiceModel.ClientBase

我做错了什么?

提前致谢。

1 个答案:

答案 0 :(得分:1)

好的,通过一些搜索,我发现了这个: C# generic ClientBase with interface confusion

我的代码中有一些错误,所以,我改为:

 public static TRet CallWebServiceAndReturn<TInterface, TClient, TRet>(TClient client, string methodName, object[] parameters, bool cacheThis)
        where TInterface : class
        where TClient : ClientBase<TInterface>, TInterface
    {
       //......
    }

使用此电话:

 MenuSoapClient menuClient = new MenuSoapClient();
        ret = WSClientService.CallWebServiceAndReturn<MenuSoap, MenuSoapClient, CategoryType[]>(menuClient, "GetSuperiorMenu", parameters, 
true);