locked
Calling webservice (WCF) with Invoke method from MethodInfo class RRS feed

  • Question

  • User-839182035 posted

    Hi.

    I have a web application without reference to webservice. My application needs connect with any web services. To make this, the application get a list of web services when it need.

    To call this web services, we create an instance of MethodInfo class and use the Invoke method like this:

    methodInfo.Invoke(instance, BindingFlags.InvokeMethod, null, null, null);

    This work fine. The next step would be stop service at any moment. Either a timeuot or a simple button.

    var thread = new Thread(() =>
    {  
     methodInfo.Invoke(instance, BindingFlags.InvokeMethod, null, null, null);                        
    });
    
    thread.Start();
    
    if (!thread.Join(TimeSpan.FromSeconds(60)))
    {
      thread.Abort();
      throw new Exception("Timeout - 1 minute");
    }

    The code above is work fine. The instance parameter contains the name of the web service that I need to connect. However if I verify in database, the process is still running.

    Can anyone help me, please?

    Thanks

    Thiago

    Thursday, May 9, 2019 11:48 AM

All replies

  • User475983607 posted

    I have a web application without reference to webservice. My application needs connect with any web services. To make this, the application get a list of web services when it need.

    To call this web services, we create an instance of MethodInfo class and use the Invoke method like this:

    This approach is simply not possible.  MethodInfo class can only see methods that exist in the current assembly.  If this approach works then there is a service reference or code that calls the service and you should use that code.

    Thursday, May 9, 2019 12:14 PM
  • User-839182035 posted

    Hi.

    I don't have the service reference in my application. See the code below:

    private void ExecuteWCF(Job job)
            {
                try
                {
                    Uri mexAddress = new Uri(job.Caminho);
                    MetadataExchangeClientMode mexMode = MetadataExchangeClientMode.HttpGet;
    
                    string contractName = job.Interface;
                    string operationName = job.Metodo;
    
                    MetadataExchangeClient mexClient = new MetadataExchangeClient(mexAddress, mexMode);
                    mexClient.ResolveMetadataReferences = true;
                    mexClient.MaximumResolvedReferences = 200000;
                    mexClient.OperationTimeout = new TimeSpan(0, 30, 0);
    
                    MetadataSet metaSet = mexClient.GetMetadata();
    
                    WsdlImporter importer = new WsdlImporter(metaSet);
                    Collection<ContractDescription> contracts = importer.ImportAllContracts();
                    ServiceEndpointCollection allEndpoints = importer.ImportAllEndpoints();
    
                    ServiceContractGenerator generator = new ServiceContractGenerator();
                    var endpointsForContracts = new Dictionary<string, IEnumerable<ServiceEndpoint>>();
    
                    foreach (ContractDescription contract in contracts)
                    {
                        generator.GenerateServiceContractType(contract);
                        endpointsForContracts[contract.Name] = allEndpoints.Where(
                            se => se.Contract.Name == contract.Name).ToList();
                    }
    
                    if (generator.Errors.Count != 0)
                        throw new Exception("There were errors during code compilation.");
    
                    CodeGeneratorOptions options = new CodeGeneratorOptions();
                    options.BracingStyle = "C";
                    CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("C#");
    
                    CompilerParameters compilerParameters = new CompilerParameters(
                        new string[] { 
                    "System.dll", "System.ServiceModel.dll", 
                    "System.Runtime.Serialization.dll" });
                    compilerParameters.GenerateInMemory = true;
    
                    CompilerResults results = codeDomProvider.CompileAssemblyFromDom(
                        compilerParameters, generator.TargetCompileUnit);
    
                    if (results.Errors.Count > 0)
                    {
                        throw new Exception("There were errors during generated code compilation");
                    }
                    else
                    {
                        Type clientProxyType = results.CompiledAssembly.GetTypes().First(
                            t => t.IsClass &&
                                t.GetInterface(contractName) != null &&
                                t.GetInterface(typeof(ICommunicationObject).Name) != null);
    
                        ServiceEndpoint se = endpointsForContracts[contractName].First();
    
                        if (job.TipoIntervalo == TipoIntervalo.Hora)
                            se.Binding.SendTimeout = TimeSpan.FromHours(job.TempoEstimado);
                        else if (job.TipoIntervalo == TipoIntervalo.Minuto)
                            se.Binding.SendTimeout = TimeSpan.FromMinutes(job.TempoEstimado);                    
                        
                        se.Binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
                        se.Binding.OpenTimeout = new TimeSpan(0, 10, 0);
                        se.Binding.CloseTimeout = new TimeSpan(0, 10, 0);
    
                        object instance = results.CompiledAssembly.CreateInstance(
                            clientProxyType.Name,
                            false,
                            System.Reflection.BindingFlags.CreateInstance,
                            null,
                            new object[] { se.Binding, se.Address },
                            CultureInfo.CurrentCulture, null);
    
                        var methodInfo = instance.GetType().GetMethod(operationName);
    
                        var thread = new Thread(() =>
                        {
                            Thread.CurrentThread.IsBackground = true;
                            /* run your code here */                        
    
                            methodInfo.Invoke(instance, BindingFlags.InvokeMethod, null, null, null);                        
                        });
    
                        thread.Start();
    
                        if (!thread.Join(TimeSpan.FromSeconds(60)))
                        {
                            thread.Abort();
                            throw new Exception("Timeout - 1 minute");
                        }                    
                    }
                }            
                catch (Exception ex)
                {
                }
            }

    mexAddress contains the link (wsdl from web service WCF).

    After that, the application get all resources to call this web service.

    Thursday, May 9, 2019 1:46 PM
  • User475983607 posted

    I'm not sure if WCF handles an cancellation token, I don't think it does out-of-the-box but there are open source solutions.

    https://github.com/max-ieremenko/ServiceModel.Cancellation

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/318df640-9a30-4dd4-a13c-1f5b03cbe619/wcf-async-pattern-with-tasks-and-cancellation?forum=wcf

    Thursday, May 9, 2019 2:09 PM