Consume webservice dynamically

Asked

Viewed 14,922 times

3

I am developing an Asp.net+c# application that will access some public webservices. I would like to do something flexible and easy to maintain in the future. I thought of calling the webservice by passing its address and input parameters and storing the result in a dynamic list.

It is possible to access a webservice and receive the result dynamically, that is, without having to reference the webservice in Visual Studio?

3 answers

3


I needed something like this some time ago, and I got excellent results with this function:

    [System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.Demand, Unrestricted = true)]
    internal static object CallWebService(string webServiceAsmxUrl, string serviceName, string methodName, object[] args)
    {

        // Veja http://social.msdn.microsoft.com/Forums/vstudio/en-US/39138d08-aa08-4c0c-9a58-0eb81a672f54/adding-a-web-reference-dynamically-at-runtime?forum=csharpgeneral

        System.Net.WebClient client = new System.Net.WebClient();

        // Connect To the web service

        System.IO.Stream stream = client.OpenRead(webServiceAsmxUrl + "?wsdl");

        // Now read the WSDL file describing a service.

        var description = System.Web.Services.Description.ServiceDescription.Read(stream);

        ///// LOAD THE DOM /////////

        // Initialize a service description importer.

        var importer = new System.Web.Services.Description.ServiceDescriptionImporter();

        importer.ProtocolName = "Soap12"; // Use SOAP 1.2.

        importer.AddServiceDescription(description, null, null);

        // Generate a proxy client.

        importer.Style = System.Web.Services.Description.ServiceDescriptionImportStyle.Client;

        // Generate properties to represent primitive values.

        importer.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;

        // Initialize a Code-DOM tree into which we will import the service.

        var nmspace = new System.CodeDom.CodeNamespace();

        var unit1 = new System.CodeDom.CodeCompileUnit();

        unit1.Namespaces.Add(nmspace);

        // Import the service into the Code-DOM tree. This creates proxy code that uses the service.

        var warning = importer.Import(nmspace, unit1);

        if (warning == 0) // If zero then we are good to go
        {


            // Generate the proxy code

            var provider1 = System.CodeDom.Compiler.CodeDomProvider.CreateProvider("CSharp");

            // Compile the assembly proxy with the appropriate references

            string[] assemblyReferences = new string[5] { "System.dll", "System.Web.Services.dll", "System.Web.dll", "System.Xml.dll", "System.Data.dll" };

            var parms = new System.CodeDom.Compiler.CompilerParameters(assemblyReferences);

            var results = provider1.CompileAssemblyFromDom(parms, unit1);

            // Check For Errors

            if (results.Errors.Count > 0)
            {

                foreach (System.CodeDom.Compiler.CompilerError oops in results.Errors)
                {


                    System.Diagnostics.Debug.WriteLine("========Compiler error============");

                    System.Diagnostics.Debug.WriteLine(oops.ErrorText);

                }

                throw new System.Exception("Compile Error Occured calling webservice. Check Debug ouput window.");

            }

            // Finally, Invoke the web service method

            object wsvcClass = results.CompiledAssembly.CreateInstance(serviceName);

            var mi = wsvcClass.GetType().GetMethod(methodName);

            return mi.Invoke(wsvcClass, args);

        }

        else
        {

            return null;

        }

    }

Example of use:

    string link = "http://localhost:19656/serviço.asmx";

    object[] args = { "teste" };

    var ws = CallWebService(link, "MeuServiço", "MeuMetodo", args);

    if (ws != null)
    {
       str = ws.ToString(); // Resultado
    }
  • Exactly what I need! Tks!

  • Glad I could help; hugs

0

Depending on the webservice technology you can make the requests only using Jquery passing normal values or even with JSON.

Example of Webservice calling passing the values by JSON:

$.ajax({
  type: "POST",
  url: "http://webserviceURL.asmx/nomeDoMetodo",
  data: "{'parametro: valor'}", // somente se o método exigir parâmetros se não é so deixar 'data: "{}"'
  contentType: "application/json; charset=utf-8",
  dataType: "json",
  success: function(msg) { 
    // seu código quando o retorno for sucesso
    alert(msg.d);
  },
  failure: function(msg) { 
    // seu código quando falhar
    alert('Erro!');
  }
});

That code I posted here too. Out that you can work with jsonp and crossdomain only informing them, see more about the $.ajax here.

Other examples, by requesting $.get or it could be with the $.post:

$.get("http://urlSite/webservice.asmx", { valor: "foo"},
  function(data){
    alert("Retorno: " + data);
  });

0

Another alternative is to use object orientation in its purest form, i.e., to define an interface. Ex.:

public interface IMeuServicoExterno {
  IList<MeuResultado> MinhaChamada(MeuTipoQueRepresentaMeuRequest inputParams);
}

Then make a concrete class, can be in an external Assembly and this yes makes the reference to the external Web Service. You can choose the implementation at runtime, using a dependency injection container or even a "Strategy" Pattern design. It is a way to maintain dynamic implementation even if the means of implementation is not the web service itself.

The essence of this is the concept of Inversion of dependencies, one of the foundations of the POO.

  • Cool Eric! I will try to implement using these concepts... Thanks!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.