特定の URL、サービス名、メソッド名、および引数に対して実行時に Web サービスを動的に呼び出すことができるコードがあります。問題は、コンパイルしようとしている WSDL に<import namespace="..." location="..."/>
タグが含まれている場合に発生します。次のエラーがスローされます。
名前空間 ... のサービスの説明がありません
おそらく、最初に import タグから参照された WSDL をコンパイルする必要があります。参照された WSDL が別の WSDL を参照する可能性があることを念頭に置いて、これを行うにはどうすればよいでしょうか? 以下は私が使用しているコードです。
public static object CallWebService(string url, string serviceName, string methodName, string userName, string password, ServiceDescription wsdl, ILogger logger, object[] args)
{
var client = new WebClient();
if (userName.Length > 0)
{
client.Credentials = new NetworkCredential(userName, password);
}
var stream = client.OpenRead(url + "?wsdl");
if (stream != null)
{
var description = ServiceDescription.Read(stream);
wsdl = description;
var importer = new ServiceDescriptionImporter
{
ProtocolName = "Soap12",
Style = ServiceDescriptionImportStyle.Client,
CodeGenerationOptions = CodeGenerationOptions.GenerateProperties
};
importer.AddServiceDescription(wsdl, null, null);
var nameSpace = new CodeNamespace();
var unit = new CodeCompileUnit();
unit.Namespaces.Add(nameSpace);
**var warning = importer.Import(nameSpace, unit);** // Error occurs here
if (warning == 0)
{
var provider = CodeDomProvider.CreateProvider("CSharp");
var assemblyReferences = new[] { "System.dll", "System.Web.Services.dll", "System.Web.dll", "System.Xml.dll", "System.Data.dll" };
var parameters = new CompilerParameters(assemblyReferences);
var results = provider.CompileAssemblyFromDom(parameters, unit);
if (results.Errors.Count > 0)
{
logger.Info("Compiler errors: " + results.Errors.Count);
foreach (var error in results.Errors)
{
logger.Info(error.ToString());
}
throw new Exception("Compile Error Occured calling webservice.");
}
var service = results.CompiledAssembly.CreateInstance(serviceName);
if (service != null)
{
var methods = service.GetType().GetMethods();
var method = service.GetType().GetMethod(methodName);
if (method == null)
{
var message = "Method: " + methodName + " is invalid. Valid Methods are: ";
message = methods.Aggregate(message, (current, methodInfo) => current + methodInfo.Name + "; ");
throw new Exception(message);
}
return method.Invoke(service, args);
}
logger.Info("Service invocation error. ServiceName provided: " + serviceName);
return null;
}
return null;
}
return null;
}