2

特定の 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;
}
4

1 に答える 1

0

少し遅いかもしれませんが、グーグル検索者にとっては悪くありません。xsd ファイルをフラット化する必要があります。それらを解析し、インポート部分を探します。このインポート部分を取得し、インポートの場所のパスにあるファイルを追加します。これで始められるはずです: http://arstechnica.com/civis/viewtopic.php?f=20&t=180943

于 2014-07-30T11:02:08.960 に答える