Asked by:
Calling webservice (WCF) with Invoke method from MethodInfo class

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.
Thursday, May 9, 2019 2:09 PM