Consume webservice dynamically

3

I'm 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.

Is it possible to access a webservice and receive the result dynamically, ie without having to reference the webservice in Visual Studio?

    
asked by anonymous 13.02.2014 / 17:23

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 usage:

    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
    }
    
13.02.2014 / 17:36
0

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

Example of WebService call passing 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!');
  }
});

This code I posted here too . Other than that you can work with jsonp and crossdomain only by reporting them, see more about $ .ajax here .

Other examples, making requests with $.get or can be with $.post :

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

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

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

Then, to make a concrete class, it can be in an external assembly and it does refer to the external Web Service. You can choose the implementation at runtime, using a dependency injection container or even a design pattern "Strategy". It is a way to keep the implementation dynamic even if the implementation medium is not the web service itself.

The essence of this is the Dependency Reversal concept, one of the foundations of OOP. / p>     

18.02.2014 / 02:25