Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic method to call WebServices

Tags:

c#

generics

I'm trying to make a method that controlls calls from my frontend to the backend. To do this, I has maded a generic method (cause I have a lot of 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;
    }

I don't realy know what the generic TClient must looks like. When I inspect the auto generated client from Visual Studio, It extends a ClientBase, so, I concluded that I just need to put this in the "where" clausule:

 where TClient : ClientBase<TClient>

The auto generated SoapClient implementation:

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

At this point, I don't have any erros, but then, I try to code some lines:

 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

In the last line, Visual Studio gives me an error on "menuClient", first argument:

Cannot convert from frontend.WSMenu.MenuSoapClient to System.ServiceModel.ClientBase

What I'm doing wrong?

Thanks in advance.

like image 852
William Borgo Avatar asked Dec 04 '25 10:12

William Borgo


1 Answers

Ok, with some searches, I found this: C# generic ClientBase with interface confusion

There is some mistakes in my code, so, I changed to this:

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

An call with this:

 MenuSoapClient menuClient = new MenuSoapClient();
        ret = WSClientService.CallWebServiceAndReturn<MenuSoap, MenuSoapClient, CategoryType[]>(menuClient, "GetSuperiorMenu", parameters, 
true);
like image 171
William Borgo Avatar answered Dec 06 '25 23:12

William Borgo