0

Here is an example of how I am calling a web method for a web service for an object, using VB.NET.

Dim tt As New GetSurveyLink
Dim result As String = tt.GetSurveyLinkString(New List(Of String)({"A","B"})

Can someone tell me how to use the Class I have listed below to accomplish the same type of operation?

Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.CodeDom.Compiler
Imports System.Security.Permissions
Imports System.Reflection
Imports System.CodeDom
Imports System.Diagnostics

Namespace DynamicSoap
    Public Class Class_DynamicWebService
        Public Class Class_ObjectCreateThenCallItem
            Public MethodName As String
            Public Data As Object = Nothing
        End Class
        Public Enum WebServiceType
            StraightCall
            ObjectCreateThenCall
        End Enum
        Private Class Class_WebService
            Public serviceName As String
            Public client As New System.Net.WebClient
            Public stream As System.IO.Stream
            Public description As System.Web.Services.Description.ServiceDescription
            Public importer As New System.Web.Services.Description.ServiceDescriptionImporter
            Public codenamespace As New CodeNamespace
            Public codeunit As New CodeCompileUnit
            Public warning As System.Web.Services.Description.ServiceDescriptionImportWarnings
            Public provider As CodeDomProvider
            Public assemblyReferences As String()
            Public parms As CompilerParameters
            Public results As CompilerResults
            Public wsvcClass As [Object]
            Public mi As MethodInfo
        End Class
        Private Shared WebServiceList As List(Of Class_WebService)

        Public Sub New()
            WebServiceList = New List(Of Class_WebService)
        End Sub

        Public Shared Function CallWebService(WST As WebServiceType, webServiceAsmxUrl As String, serviceName As String, methodName As String, _
           Optional args_StraightCall As List(Of String) = Nothing, _
           Optional ObjectCreateThenCallItems As List(Of Class_ObjectCreateThenCallItem) = Nothing) As [Object]

            Try
                Dim theWSDetail As Class_WebService = WebServiceList.Find(Function(o As Class_WebService) o.serviceName = serviceName)
                If theWSDetail Is Nothing Then
                    Dim thisWS As New Class_WebService
                    With thisWS
                        .serviceName = serviceName
                        '-Connect To the web service
                        .stream = .client.OpenRead(webServiceAsmxUrl + "?wsdl")
                        'Read the WSDL file describing a service.
                        .description = System.Web.Services.Description.ServiceDescription.Read(.stream)
                        'Load the DOM
                        '--Initialize a service description importer.
                        .importer.ProtocolName = "Soap12" 'Use SOAP 1.2.
                        .importer.AddServiceDescription(.description, Nothing, Nothing)
                        '--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.
                        .codeunit.Namespaces.Add(.codenamespace)
                        'Import the service into the Code-DOM tree.
                        'This creates proxy code that uses the service.
                        .warning = .importer.Import(.codenamespace, .codeunit)
                        If .warning = 0 Then
                            '--Generate the proxy code
                            .provider = CodeDomProvider.CreateProvider("VisualBasic")
                            '--Compile the assembly proxy with the
                            .assemblyReferences = New String() {"System.dll", "System.Web.Services.dll", "System.Web.dll", "System.Xml.dll", "System.Data.dll"}
                            '--Add parameters
                            .parms = New CompilerParameters(.assemblyReferences)
                            .parms.GenerateInMemory = True
                            .results = .provider.CompileAssemblyFromDom(.parms, .codeunit)
                            '--Check For Errors
                            If .results.Errors.Count > 0 Then
                                Dim theError As String = ""
                                For Each oops As CompilerError In .results.Errors
                                    System.Diagnostics.Debug.WriteLine("========Compiler error============")
                                    System.Diagnostics.Debug.WriteLine(oops.ErrorText)
                                    theError &= oops.Line & "  -  " & oops.ErrorText & vbNewLine
                                Next
                                Throw New Exception("Compile Error Occured calling WebService.", New Exception(theError))
                            End If
                            Select Case WST
                                Case WebServiceType.StraightCall
                                    '--Finally, Invoke the web service method
                                    .wsvcClass = .results.CompiledAssembly.CreateInstance(serviceName)
                                    .mi = .wsvcClass.[GetType]().GetMethod(methodName)
                                    Dim theReturn As [Object] = .mi.Invoke(.wsvcClass, args_StraightCall.ToArray)
                                    WebServiceList.Add(thisWS)
                                    Return theReturn
                            End Select
                        Else
                            Return Nothing
                        End If
                    End With
                Else
                    Select Case WST
                        Case WebServiceType.StraightCall
                            With WebServiceList(WebServiceList.IndexOf(theWSDetail))
                                Dim theReturn As [Object] = .mi.Invoke(.wsvcClass, args_StraightCall.ToArray)
                                Return theReturn
                            End With
                    End Select
                End If
            Catch ex As Exception
                Throw ex
            End Try
        End Function
    End Class
End Namespace

I can currently only call a web method, pass in parameters, then return a value. This is just too limiting.

svick
  • 236,525
  • 50
  • 385
  • 514
open7
  • 43
  • 7
  • ASMX is a legacy technology, and should not be used for new development. WCF or ASP.NET Web API should be used for all new development of web service clients and servers. One hint: Microsoft has retired the [ASMX Forum](http://social.msdn.microsoft.com/Forums/en-US/asmxandxml/threads) on MSDN. – John Saunders Jan 07 '14 at 00:05
  • I'm using another company's web service, so I don't have the luxury of having it changed over to another type. With ASMX out of the question, is it possible to use the class above to accomplish what I inquired about above? – open7 Jan 07 '14 at 14:44
  • Maybe you don't realize that the technology you are using is a _part_ of ASMX. But you don't have to use the ASMX technology just to call some other web service. Have you tried just using "Add Service Reference"? – John Saunders Jan 07 '14 at 15:08
  • Good question. I'm trying to use CodeDom to dynamically call web services without having to add the services to my project. Bascially limiting the size of the application and frequency of release of the application. This is why I'm attempting to take this approach. – open7 Jan 07 '14 at 15:41
  • Suggestion: put all the service references into a single class library project. That will be the only DLL you need to update when services change. Also, you may find that a T4 template is easier to use than CODEDOM. Lastly, I still strongly recommend that you at least build your proxy classes to use the WCF client code in a similar manner to what "Add Service Reference" does. Since you're generating the code, you have even less reason to be stuck in the past. – John Saunders Jan 07 '14 at 15:54

0 Answers0