Question :
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?
Answer :
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
}
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);
});
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>