简体   繁体   English

C#调用导航Web服务而不添加Web引用

[英]C# call nav web service without adding a web reference

I am working on a project that requires me to connect to a Microsoft Dynamics NAV web service, and get some data. 我正在做一个项目,该项目需要我连接到Microsoft Dynamics导航Web服务并获取一些数据。 However, we do not have access to this web service from the development environment, so I am unable to add a Web Reference to my project, in the usual way. 但是,我们无法从开发环境访问此Web服务,因此无法以通常的方式向我的项目添加Web引用。

Is there a way, to "dynamically" connect to the web reference, in run-time, by providing URL, user, password & domain? 有没有办法通过提供URL,用户,密码和域在运行时“动态”连接到Web参考? Then create dynamic objects, and call the methods of the web service? 然后创建动态对象,并调用Web服务的方法? (So I would make a console application, that only runs on the production environment, because there's the access to the web service) (因此,我将制作一个仅在生产环境上运行的控制台应用程序,因为可以访问Web服务)

From my initial research I found a couple of ways, where there's a function, that returns object type objects. 从最初的研究中,我发现了几种方法,其中有一个函数可以返回对象类型的对象。 I usually have credential problems with this : Unauthorized access (401) 我通常在此方面存在凭证问题:未经授权的访问(401)

I am very new to these web services, by the way... 顺便说一下,我对这些Web服务还很陌生...

Method i've been using so far, without any luck: 到目前为止,我一直使用的方法没有任何运气:

internal static object CallWebService(string webServiceAsmxUrl, string serviceName, string methodName, object[] args)

    {
        System.Net.WebClient client = new System.Net.WebClient();
        CredentialCache cc = new CredentialCache();
        cc.Add(
            new Uri(webServiceAsmxUrl),
            "NTLM",
            new NetworkCredential("user", "password", "domain"));
        client.Credentials = cc;
        // Connect To the web service
        System.IO.Stream stream = client.OpenRead(webServiceAsmxUrl + "?wsdl");

        // Now read the WSDL file describing a service.
        ServiceDescription description = ServiceDescription.Read(stream);
        ///// LOAD THE DOM /////////

        // Initialize a service description importer.

        ServiceDescriptionImporter importer = new ServiceDescriptionImporter();

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

        importer.AddServiceDescription(description, null, null);

        // Generate a proxy client.

        importer.Style = 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.

        CodeNamespace nmspace = new CodeNamespace();

        CodeCompileUnit unit1 = new CodeCompileUnit();

        unit1.Namespaces.Add(nmspace);

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

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

        //THIS IS WHERE IT's NOT COMPLYING. warning will be "NoGeneratedCode"
        if (warning == 0) // If zero then we are good to go

        {

            // Generate the proxy code

            CodeDomProvider provider1 = 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" };

            CompilerParameters parms = new CompilerParameters(assemblyReferences);

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

            // Check For Errors
            if (results.Errors.Count > 0)

            {

                foreach (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);

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

            return mi.Invoke(wsvcClass, args);

        }

        else

        {

            return null;

        }

    }

It always returns null. 它始终返回null。

Is it web service (or) a WCF service? 它是Web服务(还是WCF服务)? Cause if it a WCF service then you can use SvcUtil.exe to access the service. 原因是如果它是WCF服务,则可以使用SvcUtil.exe访问该服务。 If it's a webservice then you can access the service from any web browser provided you know the WSDL file name like below 如果是网络服务,那么您可以从任何网络浏览器访问该服务,前提是您知道如下所示的WSDL文件名

http://servername/apppath/webservicename.asmx

(OR) (要么)

 http://servername/vdir/webservicename.asmx/Methodname?parameter=value

See this Documentation for more information 有关更多信息,请参见本文档

I know it's an old post but I just stumbled across the exact same issue. 我知道这是一篇旧文章,但我偶然发现了完全相同的问题。 I fixed it by changing 我通过更改来解决

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

to

importer.ProtocolName = "Soap"; // Woohoo

The allowed values for the ProtocolName are: ProtocolName的允许值为:

  • "Soap" “肥皂”
  • "Soap12" “SOAP12”
  • "HttpPost" “HttpPost”
  • "HttpGet" “HTTPGET”
  • "HttpSoap" “HttpSoap”

as per the documentation . 根据文档

Hope that helps someone who comes across a similar issue! 希望对遇到类似问题的人有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM