title: Dynamically invoke WCF Service from its URI (http://ip:port/Service1.svc?WSDL)
body: <p>So here it is:</p>
  
  <p>I am trying to invoke a WCF Service's method from with in a windows form client application. I do not have the Contract Class Definition. The only thing I have is the Service's URI, which is <a href="http://ip:port/Service1.svc">http://ip:port/Service1.svc</a>. </p>
  
  <p>So I thought i could make a proxy class for that. I want to make the proxy class at run time so any external tool to create a proxy class and import to project can't help me.</p>
  
  <p>I managed to make the proxy class on the fly. Here's the code:</p>
  
  <pre><code>        Dim mexClient As MetadataExchangeClient = New MetadataExchangeClient(New Uri(webServicesWSDLUrl), MetadataExchangeClientMode.HttpGet)
          mexClient.ResolveMetadataReferences = True
          Dim metaDocs As MetadataSet = mexClient.GetMetadata()
  
          Dim importer As WsdlImporter = New WsdlImporter(metaDocs)
          Dim generator As ServiceContractGenerator = New ServiceContractGenerator()
  
          Dim dataContractImporter As New Object
          Dim xsdDCImporter As XsdDataContractImporter
          If (Not importer.State.TryGetValue(GetType(XsdDataContractImporter), dataContractImporter)) Then
  
              Console.WriteLine("Couldn't find the XsdDataContractImporter! Adding custom importer.")
              xsdDCImporter = New XsdDataContractImporter()
              xsdDCImporter.Options = New ImportOptions()
              importer.State.Add(GetType(XsdDataContractImporter), xsdDCImporter)
  
          Else
  
              xsdDCImporter = TryCast(dataContractImporter, XsdDataContractImporter)
              If (xsdDCImporter.Options Is Nothing) Then
  
                  Console.WriteLine("There were no ImportOptions on the importer.")
                  xsdDCImporter.Options = New ImportOptions()
              End If
  
          End If
  
          Dim exts As System.Collections.IEnumerable = importer.WsdlImportExtensions
          Dim newExts As New System.Collections.Generic.List(Of IWsdlImportExtension)
          For Each ext As IWsdlImportExtension In exts
              Console.WriteLine("Default WSDL import extensions: {0}", ext.GetType().Name)
              newExts.Add(ext)
          Next
  
          Dim polExts As System.Collections.IEnumerable = importer.PolicyImportExtensions
          importer = New WsdlImporter(metaDocs, polExts, newExts)
  
  
          Dim Contracts As System.Collections.ObjectModel.Collection(Of ContractDescription) = importer.ImportAllContracts()
          importer.ImportAllEndpoints()
          importer.ImportAllBindings()
  
  
  
          For Each contract As ContractDescription In Contracts
              generator.GenerateServiceContractType(contract)
          Next
  
  
          If generator.Errors.Count &lt;&gt; 0 Then
              Throw New Exception("There were errors during code compilation.")
          End If
  
  
          Dim nmspace As CodeNamespace = New CodeNamespace()
          Dim unit1 As CodeCompileUnit = New CodeCompileUnit()
          unit1.Namespaces.Add(nmspace)
  
  
          Dim CodeDomProvider As System.CodeDom.Compiler.CodeDomProvider = System.CodeDom.Compiler.CodeDomProvider.CreateProvider("VB")
  
          Dim assemblyReferences() As String
          assemblyReferences = New String() {"System.dll", _
              "System.Web.Services.dll", "System.Web.dll", _
              "System.Xml.dll", "System.Data.dll"}
          Dim parms As CompilerParameters = New CompilerParameters(assemblyReferences)
          parms.GenerateInMemory = True '(Thanks for this line nikolas)
  
          'CompilerRsults
          results = CodeDomProvider.CompileAssemblyFromDom(parms, generator.TargetCompileUnit) 
  </code></pre>
  
  <p>Now using the <code>results</code> I make an Instance of my WebService (<code>methodName = "GetData"</code>, <code>args = new Object() { 4 }</code> ): See Below..</p>
  
  <pre><code>        Dim wsvcClass As Object = results.CompiledAssembly.CreateInstance(serviceName)
          Dim retValue As Object = wsvcClass.GetType().InvokeMember(methodName, BindingFlags.InvokeMethod, Nothing, wsvcClass, args)
  </code></pre>
  
  <p>The last command throws an Exception</p>
  
  <pre><code>    A first chance exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
  System.ServiceModel.EndpointNotFoundException: There was no endpoint listening at http://ip:port/Service1.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details. ---&gt; System.Net.WebException: The remote server returned an error: (404) Not Found.
     at System.Net.HttpWebRequest.GetResponse()
     at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
     --- End of inner exception stack trace ---
  
  Server stack trace: 
     at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
     at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
     at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
     at System.ServiceModel.Dispatcher.ReA first chance exception of type 'System.NullReferenceException' occurred in ThirdPartyAPIClientApp.exe
  questChannelBinder.Request(Message message, TimeSpan timeout)
     at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
     at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
     at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
  
  Exception rethrown at [0]: 
     at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
     at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp; msgData, Int32 type)
     at IService1.GetData(Int32 value)
     at Service1Client.GetData(Int32 value)
  </code></pre>
  
  <p>Below You can find the web.config of the Web Service and the App.config of the client application</p>
  
  <blockquote>
    <p>web.config</p>
  </blockquote>
  
  <pre><code>    &lt;?xml version="1.0"?&gt;
  &lt;configuration&gt;
  
    &lt;system.web&gt;
      &lt;compilation debug="true" strict="false" explicit="true" targetFramework="4.0" /&gt;
    &lt;/system.web&gt;
  
    &lt;system.diagnostics&gt;
      &lt;sources&gt;
        &lt;source name="System.ServiceModel.MessageLogging"&gt;
          &lt;listeners&gt;
            &lt;add name="messages"
            type="System.Diagnostics.XmlWriterTraceListener"
            initializeData="c:\logs\messages.svclog" /&gt;
          &lt;/listeners&gt;
        &lt;/source&gt;
      &lt;/sources&gt;
    &lt;/system.diagnostics&gt;
  
    &lt;system.serviceModel&gt;
  
      &lt;diagnostics&gt;
        &lt;messageLogging
             logEntireMessage="true"
             logMalformedMessages="false"
             logMessagesAtServiceLevel="true"
             logMessagesAtTransportLevel="false"
             maxMessagesToLog="3000"
             maxSizeOfMessageToLog="2000"/&gt;
      &lt;/diagnostics&gt;
  
      &lt;services&gt;
        &lt;!-- Note: the service name must match the configuration name for the service implementation. --&gt;
        &lt;service name="WcfService1.Service1" behaviorConfiguration="BasicHttpBinding_This" &gt;
          &lt;endpoint address="/Service1.svc" contract="WcfService1.IService1" binding="basicHttpBinding" bindingNamespace="http://ip:port/WCF1_Test" /&gt;
          &lt;endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" /&gt;
        &lt;/service&gt;
      &lt;/services&gt;
  
  
      &lt;behaviors&gt;
        &lt;serviceBehaviors&gt;
          &lt;behavior name="BasicHttpBinding_This"&gt;
            &lt;!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --&gt;
            &lt;serviceMetadata httpGetEnabled="true"/&gt;
            &lt;!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information --&gt;
            &lt;serviceDebug includeExceptionDetailInFaults="false"/&gt;
          &lt;/behavior&gt;
        &lt;/serviceBehaviors&gt;
      &lt;/behaviors&gt;
  
      &lt;bindings&gt;
  
  
        &lt;basicHttpBinding&gt;
  
          &lt;binding name="BasicHttpBinding_This" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            bypassProxyOnLocal="false"  hostNameComparisonMode="StrongWildcard"
            maxBufferPoolSize="200000000000000" maxReceivedMessageSize="200000000000000"
            messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
            allowCookies="false"&gt;
            &lt;readerQuotas maxDepth="32" maxStringContentLength="2147483647"
              maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /&gt;
  
            &lt;security mode="None"&gt;
              &lt;transport clientCredentialType="Windows" proxyCredentialType="None"
                realm="" /&gt;
              &lt;message clientCredentialType="UserName" algorithmSuite="Default" /&gt;
            &lt;/security&gt;
          &lt;/binding&gt;
        &lt;/basicHttpBinding&gt;
      &lt;/bindings&gt;
      &lt;serviceHostingEnvironment multipleSiteBindingsEnabled="true" /&gt;
    &lt;/system.serviceModel&gt;
    &lt;system.webServer&gt;
      &lt;modules runAllManagedModulesForAllRequests="true"/&gt;
    &lt;/system.webServer&gt;
  
  &lt;/configuration&gt;
  </code></pre>
  
  <blockquote>
    <p>App.config</p>
  </blockquote>
  
  <pre><code> &lt;?xml version="1.0"?&gt;
  &lt;configuration&gt;
      &lt;startup&gt;
          &lt;supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/&gt;
      &lt;/startup&gt;
  
      &lt;system.serviceModel&gt;
          &lt;bindings&gt;
            &lt;basicHttpBinding&gt;
              &lt;binding name="BasicHttpBinding_This" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                bypassProxyOnLocal="false"  hostNameComparisonMode="StrongWildcard"
                maxBufferPoolSize="200000000" maxReceivedMessageSize="200000000"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                allowCookies="false"&gt;
                &lt;readerQuotas maxDepth="32" maxStringContentLength="200000000"
                  maxArrayLength="200000000" maxBytesPerRead="200000000" maxNameTableCharCount="200000000" /&gt;
  
                &lt;security mode="None"&gt;
                  &lt;transport clientCredentialType="Windows" proxyCredentialType="None"
                    realm="" /&gt;
                  &lt;message clientCredentialType="UserName" algorithmSuite="Default" /&gt;
                &lt;/security&gt;
              &lt;/binding&gt;
            &lt;/basicHttpBinding&gt;
          &lt;/bindings&gt;
          &lt;client&gt;
  
            &lt;endpoint address="http://ip:port/Service1.svc"
                  binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_This"
                  contract="IService1" name="BasicHttpBinding_This" /&gt;
  
          &lt;/client&gt;
      &lt;/system.serviceModel&gt;
  &lt;/configuration&gt;
  </code></pre>
  
  <p>Additionally I am sending the contract and the code class of the WebService</p>
  
  <blockquote>
    <p>Contract</p>
  </blockquote>
  
  <pre><code>    &lt;ServiceContract(Namespace:="http://ip:port/WCF1_Test")&gt;
      Public Interface IService1
  
      &lt;OperationContract(isOneway:=False)&gt;
      Function GetData(ByVal value As Integer) As String
  
      &lt;OperationContract(isOneway:=False)&gt;
      Function GetDataUsingDataContract(ByVal composite As CompositeType) As CompositeType
  
      ' TODO: Add your service operations here
  
  End Interface
  
  ' Use a data contract as illustrated in the sample below to add composite types to service operations.
  
  &lt;DataContract()&gt;
  Public Class CompositeType
  
      &lt;DataMember()&gt;
      Public Property BoolValue() As Boolean
  
      &lt;DataMember()&gt;
      Public Property StringValue() As String
  
  End Class
  </code></pre>
  
  <blockquote>
    <p>Code Class</p>
  </blockquote>
  
  <pre><code>    &lt;ServiceBehavior(Namespace:="http://ip:port/WCF1_Test")&gt;
  Public Class Service1
      Implements IService1
  
      Public Sub New()
      End Sub
  
      Public Function GetData(ByVal value As Integer) As String Implements IService1.GetData
          Return String.Format("You entered: {0}", value)
      End Function
  
      Public Function GetDataUsingDataContract(ByVal composite As CompositeType) As CompositeType Implements IService1.GetDataUsingDataContract
          If composite Is Nothing Then
              Throw New ArgumentNullException("composite")
          End If
          If composite.BoolValue Then
              composite.StringValue &amp;= "Suffix"
          End If
          Return composite
      End Function
  
  End Class
  </code></pre>
  
  <p>Does any one knows the solution? What is the proper way to invoke a WCF method Dynamically if someone only knows the URI?
   PS: the Web Service is Up and Running on an IIS7</p>