MexServiceChannelBuilder.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / ComIntegration / MexServiceChannelBuilder.cs / 1 / MexServiceChannelBuilder.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
#pragma warning disable 1634, 1691
 
namespace System.ServiceModel.ComIntegration
{ 
    using System; 
    using System.ServiceModel.Description;
    using System.ServiceModel.Dispatcher; 
    using System.IO;
    using System.Reflection;
    using System.Collections.Generic;
    using System.Threading; 
    using System.ServiceModel.Channels;
    using System.ServiceModel; 
    using System.Runtime.Remoting.Proxies; 
    using System.Runtime.Remoting;
    using System.Runtime.InteropServices; 
    using System.Xml;
    using System.Xml.Schema;
    using XmlSch = System.Xml.Serialization;
    using DcNS = System.Runtime.Serialization; 
    using WsdlNS = System.Web.Services.Description;
    using DiscoNS = System.Web.Services.Discovery; 
    using System.Diagnostics; 
    using System.ServiceModel.Diagnostics;
    using System.Xml.Serialization; 
    using System.Collections.ObjectModel;
    using ConfigNS = System.ServiceModel.Configuration;

     internal class MexServiceChannelBuilder  : IProxyCreator, IProvideChannelBuilderSettings 
     {
 
          ContractDescription contractDescription = null; 
          ServiceChannelFactory serviceChannelFactory = null;
          Dictionary  propertyTable ; 
          ServiceChannel serviceChannel = null;
          ServiceEndpoint serviceEndpoint = null;
          KeyedByTypeCollection behaviors = new KeyedByTypeCollection();
          bool useXmlSerializer = false; 

//Suppressing PreSharp warning that property get methods should not throw 
#pragma warning disable 6503 
          ServiceChannelFactory IProvideChannelBuilderSettings.ServiceChannelFactoryReadWrite
          { 
               get
               {
                    if (serviceChannel != null)
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new COMException (SR.GetString (SR.TooLate), HR.RPC_E_TOO_LATE)); 
                    return serviceChannelFactory;
               } 
           } 
#pragma warning restore 6503
 
          ServiceChannel IProvideChannelBuilderSettings.ServiceChannel
          {
                get
                { 
                    return CreateChannel ();
                } 
          } 
          ServiceChannelFactory IProvideChannelBuilderSettings.ServiceChannelFactoryReadOnly
          { 
               get
               {
                    return serviceChannelFactory;
               } 
          }
 
//Suppressing PreSharp warning that property get methods should not throw 
#pragma warning disable 6503
          KeyedByTypeCollection IProvideChannelBuilderSettings.Behaviors 
          {
               get
               {
                    if (serviceChannel != null) 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new COMException (SR.GetString (SR.TooLate), HR.RPC_E_TOO_LATE));
                    return behaviors; 
               } 
           }
#pragma warning restore 6503 

          void IDisposable.Dispose ()
          {
                if (serviceChannel != null) 
                    serviceChannel.Close ();
 
          } 

          internal MexServiceChannelBuilder (Dictionary  propertyTable) 
          {
                this.propertyTable = propertyTable;
                DoMex ();
 
          }
 
          private ServiceChannel CreateChannel () 
          {
                if (serviceChannel == null) 
                {
                    lock (this)
                    {
                        if (serviceChannel == null) 
                        {
                            try 
                            { 
                                if (serviceChannelFactory == null)
                                { 
                                    FaultInserviceChannelFactory();
                                }

                                if (serviceChannelFactory == null) 
                                {
                                    DiagnosticUtility.DebugAssert("ServiceChannelFactory cannot be null at this point"); 
 
                                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false);
                                } 

                                serviceChannelFactory.Open ();

                                if (serviceEndpoint == null) 
                                {
                                    DiagnosticUtility.DebugAssert("ServiceEndpoint cannot be null"); 
 
                                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false);
                                } 

                                ServiceChannel localChannel = serviceChannelFactory.CreateServiceChannel(new EndpointAddress(serviceEndpoint.Address.Uri, serviceEndpoint.Address.Identity, serviceEndpoint.Address.Headers), serviceEndpoint.Address.Uri);
                                Thread.MemoryBarrier();
                                serviceChannel = localChannel; 

                                ComPlusChannelCreatedTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationChannelCreated, 
                                    SR.TraceCodeComIntegrationChannelCreated, serviceEndpoint.Address.Uri, contractDescription.ContractType); 

                                if (serviceChannel == null) 
                                {
                                    DiagnosticUtility.DebugAssert("serviceProxy MUST derive from RealProxy");

                                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
                                }
                            } 
                            finally 
                            {
                                if ((serviceChannel == null) && (serviceChannelFactory != null)) 
                                {
                                    serviceChannelFactory.Close ();
                                }
                            } 
                        }
                     } 
                 } 
                 return serviceChannel;
 
          }
           private ServiceChannelFactory CreateServiceChannelFactory ()
           {
                serviceChannelFactory = ServiceChannelFactory.BuildChannelFactory(serviceEndpoint) as ServiceChannelFactory; 
                if (serviceChannelFactory == null)
                { 
                    DiagnosticUtility.DebugAssert("We should get a ServiceChannelFactory back"); 

                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); 
                }
                FixupProxyBehavior ();
                return serviceChannelFactory;
           } 

           void FaultInserviceChannelFactory () 
           { 
                if (propertyTable == null)
                { 
                    DiagnosticUtility.DebugAssert("PropertyTable should not be null");

                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false);
                } 
                foreach (IEndpointBehavior behavior in behaviors)
                    serviceEndpoint.Behaviors.Add(behavior); 
                serviceChannelFactory = CreateServiceChannelFactory(); 
           }
 
         void FixupProxyBehavior()
         {
             ClientOperation operation = null;
 
             if (useXmlSerializer)
                 XmlSerializerOperationBehavior.AddBehaviors(contractDescription); 
 
             foreach (OperationDescription opDesc in contractDescription.Operations)
             { 
                 operation = serviceChannelFactory.ClientRuntime.Operations[opDesc.Name];
                 operation.SerializeRequest = true;
                 operation.DeserializeReply = true;
 
                 if (useXmlSerializer)
                     operation.Formatter = XmlSerializerOperationBehavior.CreateOperationFormatter(opDesc); 
                 else 
                     operation.Formatter = new DataContractSerializerOperationFormatter(opDesc, TypeLoader.DefaultDataContractFormatAttribute, null);
             } 
         }

          private void DoMex ()
          { 
              string mexAddress;
              string mexBindingSectionName; 
              string mexBindingConfiguration; 
              string contract;
              string contractNamespace; 
              string binding;
              string bindingNamespace;
              string address;
              string spnIdentity = null; 
              string upnIdentity = null;
              string dnsIdentity = null; 
              string mexSpnIdentity = null; 
              string mexUpnIdentity = null;
              string mexDnsIdentity = null; 
              string serializer = null;

              EndpointIdentity identity = null;
              EndpointIdentity mexIdentity = null; 

              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.Contract, out contract); 
              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.ContractNamespace, out contractNamespace); 
              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.BindingNamespace, out bindingNamespace);
              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.Binding, out binding); 
              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.MexAddress, out mexAddress);
              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.MexBinding, out mexBindingSectionName);
              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.MexBindingConfiguration, out mexBindingConfiguration);
              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.Address, out address); 
              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.SpnIdentity, out spnIdentity);
              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.UpnIdentity, out upnIdentity); 
              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.DnsIdentity, out dnsIdentity); 
              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.MexSpnIdentity, out mexSpnIdentity);
              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.MexUpnIdentity, out mexUpnIdentity); 
              propertyTable.TryGetValue (MonikerHelper.MonikerAttribute.MexDnsIdentity, out mexDnsIdentity);
              propertyTable.TryGetValue(MonikerHelper.MonikerAttribute.Serializer, out serializer);

              if (string.IsNullOrEmpty (mexAddress)) 
                  throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException  (SR.GetString (SR.MonikerMexAddressNotSpecified)));
 
              if (!string.IsNullOrEmpty(mexSpnIdentity )) 
              {
                  if ((!string.IsNullOrEmpty(mexUpnIdentity)) || (!string.IsNullOrEmpty(mexDnsIdentity))) 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException (SR.GetString (SR.MonikerIncorrectServerIdentityForMex)));
                  mexIdentity = EndpointIdentity.CreateSpnIdentity(mexSpnIdentity);
              }
              else if (!string.IsNullOrEmpty(mexUpnIdentity)) 
              {
                  if ((!string.IsNullOrEmpty(mexSpnIdentity)) || (!string.IsNullOrEmpty(mexDnsIdentity))) 
                       throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException  (SR.GetString (SR.MonikerIncorrectServerIdentityForMex))); 
                  mexIdentity = EndpointIdentity.CreateUpnIdentity(mexUpnIdentity);
              } 
              else if (!string.IsNullOrEmpty(mexDnsIdentity))
              {
                  if ((!string.IsNullOrEmpty(mexSpnIdentity)) || (!string.IsNullOrEmpty(mexUpnIdentity)))
                       throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException  (SR.GetString (SR.MonikerIncorrectServerIdentityForMex))); 
                  mexIdentity = EndpointIdentity.CreateDnsIdentity(mexDnsIdentity);
              } 
              else 
                  mexIdentity = null;
 
              if (string.IsNullOrEmpty (address))
                  throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException  (SR.GetString (SR.MonikerAddressNotSpecified)));

              if (string.IsNullOrEmpty (contract)) 
                  throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException  (SR.GetString (SR.MonikerContractNotSpecified)));
 
              if (string.IsNullOrEmpty (binding)) 
                  throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException  (SR.GetString (SR.MonikerBindingNotSpecified)));
 
              if (string.IsNullOrEmpty (bindingNamespace))
                  throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException  (SR.GetString (SR.MonikerBindingNamespacetNotSpecified)));

              if (!string.IsNullOrEmpty(spnIdentity )) 
              {
                   if ((!string.IsNullOrEmpty(upnIdentity)) || (!string.IsNullOrEmpty(dnsIdentity))) 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException (SR.GetString (SR.MonikerIncorrectServerIdentity))); 
                   identity = EndpointIdentity.CreateSpnIdentity(spnIdentity);
              } 
              else if (!string.IsNullOrEmpty(upnIdentity))
              {
                  if ((!string.IsNullOrEmpty(spnIdentity)) || (!string.IsNullOrEmpty(dnsIdentity)))
                       throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException  (SR.GetString (SR.MonikerIncorrectServerIdentity))); 
                  identity = EndpointIdentity.CreateUpnIdentity(upnIdentity);
              } 
              else if (!string.IsNullOrEmpty(dnsIdentity)) 
              {
                  if ((!string.IsNullOrEmpty(spnIdentity)) || (!string.IsNullOrEmpty(upnIdentity))) 
                       throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException  (SR.GetString (SR.MonikerIncorrectServerIdentity)));
                  identity = EndpointIdentity.CreateDnsIdentity(dnsIdentity);
              }
              else 
                  identity = null;
 
              MetadataExchangeClient resolver  = null; 
              EndpointAddress  mexEndpointAddress = new EndpointAddress (new Uri(mexAddress), mexIdentity);
 
              if (!string.IsNullOrEmpty (mexBindingSectionName))
              {
                  Binding mexBinding = null;
                  try 
                  {
                      mexBinding = ConfigLoader.LookupBinding(mexBindingSectionName, mexBindingConfiguration); 
                  } 
                  catch (System.Configuration.ConfigurationErrorsException)
                  { 
                      throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MonikerSyntaxException(SR.GetString(SR.MexBindingNotFoundInConfig, mexBindingSectionName)));
                  }

 
                  if(null == mexBinding)
                      throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MonikerSyntaxException(SR.GetString(SR.MexBindingNotFoundInConfig, mexBindingSectionName))); 
 
                  resolver = new MetadataExchangeClient(mexBinding);
              } 
              else if (string.IsNullOrEmpty (mexBindingConfiguration))
                  resolver = new MetadataExchangeClient(mexEndpointAddress);
              else
                  throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException  (SR.GetString (SR.MonikerMexBindingSectionNameNotSpecified))); 

              if (null != mexIdentity) 
              { 
                  resolver.SoapCredentials.Windows.AllowNtlm = false;
              } 

              bool removeXmlSerializerImporter = false;

              if (!String.IsNullOrEmpty(serializer)) 
              {
                  if ("xml" != serializer && "datacontract" != serializer) 
                      throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MonikerSyntaxException(SR.GetString(SR.MonikerIncorectSerializer))); 

                  if ("xml" == serializer) 
                      useXmlSerializer = true;
                  else
                      removeXmlSerializerImporter = true; // specifying datacontract will explicitly remove the Xml importer
                                                          // if this parameter is not set we will simply use indigo defaults 
              }
 
              ServiceEndpoint endpoint = null; 
              ServiceEndpointCollection serviceEndpointsRetrieved = null;
 
              WsdlImporter importer;

              try
              { 
                  MetadataSet metadataSet = resolver.GetMetadata(mexEndpointAddress);
 
                  if (useXmlSerializer) 
                      importer = CreateXmlSerializerImporter(metadataSet);
                  else 
                  {
                      if (removeXmlSerializerImporter)
                          importer = CreateDataContractSerializerImporter(metadataSet);
                      else 
                          importer = new WsdlImporter(metadataSet);
                  } 
 
                  serviceEndpointsRetrieved = this.ImportWsdlPortType(new XmlQualifiedName(contract, contractNamespace), importer);
                  ComPlusMexChannelBuilderMexCompleteTrace.Trace (TraceEventType.Verbose, TraceCode.ComIntegrationMexMonikerMetadataExchangeComplete, SR.TraceCodeComIntegrationMexMonikerMetadataExchangeComplete, serviceEndpointsRetrieved); 
              }
              catch (Exception e)
              {
                  if (DiagnosticUtility.IsFatal(e)) 
                      throw;
 
                  if(UriSchemeSupportsDisco(mexEndpointAddress.Uri)) 
                  {
                      try 
                      {
                          DiscoNS.DiscoveryClientProtocol discoClient = new DiscoNS.DiscoveryClientProtocol();
                          discoClient.UseDefaultCredentials = true;
                          discoClient.AllowAutoRedirect = true; 

                          discoClient.DiscoverAny(mexEndpointAddress.Uri.AbsoluteUri); 
                          discoClient.ResolveAll(); 
                          MetadataSet metadataSet = new MetadataSet();
 
                          foreach (object document in discoClient.Documents.Values)
                          {
                              AddDocumentToSet(metadataSet, document);
                          } 

                          if (useXmlSerializer) 
                              importer = CreateXmlSerializerImporter(metadataSet); 
                          else
                          { 
                              if (removeXmlSerializerImporter)
                                  importer = CreateDataContractSerializerImporter(metadataSet);
                              else
                                  importer = new WsdlImporter(metadataSet); 
                          }
 
                          serviceEndpointsRetrieved = this.ImportWsdlPortType(new XmlQualifiedName(contract, contractNamespace), importer); 
                          ComPlusMexChannelBuilderMexCompleteTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationMexMonikerMetadataExchangeComplete, SR.TraceCodeComIntegrationMexMonikerMetadataExchangeComplete, serviceEndpointsRetrieved);
                      } 
                      catch (Exception ex)
                      {
                          if (DiagnosticUtility.IsFatal(ex))
                              throw; 

                          throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MonikerSyntaxException(SR.GetString(SR.MonikerFailedToDoMexRetrieve, ex.Message))); 
                      } 
                  }
                  else 
                      throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException  (SR.GetString (SR.MonikerFailedToDoMexRetrieve, e.Message)));
              }

              if (serviceEndpointsRetrieved.Count == 0) 
                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException  (SR.GetString (SR.MonikerContractNotFoundInRetreivedMex)));
 
              foreach (ServiceEndpoint retrievedEndpoint in serviceEndpointsRetrieved) 
              {
                  Binding bindingSelected = retrievedEndpoint.Binding; 
                 if ((bindingSelected.Name == binding) && (bindingSelected.Namespace == bindingNamespace))
                 {
                    endpoint = retrievedEndpoint;
                    break; 
                 }
              } 
 
              if (endpoint == null)
                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError (new MonikerSyntaxException  (SR.GetString (SR.MonikerNoneOfTheBindingMatchedTheSpecifiedBinding))); 

              contractDescription = endpoint.Contract;
              this.serviceEndpoint = new ServiceEndpoint(contractDescription, endpoint.Binding, new EndpointAddress(new Uri(address), identity, (AddressHeaderCollection)null));
 
              ComPlusMexChannelBuilderTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationMexChannelBuilderLoaded,
                  SR.TraceCodeComIntegrationMexChannelBuilderLoaded, endpoint.Contract, endpoint.Binding, address); 
          } 

         static bool UriSchemeSupportsDisco(Uri serviceUri) 
         {
             return (serviceUri.Scheme == Uri.UriSchemeHttp) || (serviceUri.Scheme == Uri.UriSchemeHttps);
         }
 
         void AddDocumentToSet(MetadataSet metadataSet, object document)
         { 
             WsdlNS.ServiceDescription wsdl = document as WsdlNS.ServiceDescription; 
             XmlSchema schema = document as XmlSchema;
             XmlElement xmlDoc = document as XmlElement; 

             if (wsdl != null)
             {
                 metadataSet.MetadataSections.Add(MetadataSection.CreateFromServiceDescription(wsdl)); 
             }
             else if (schema != null) 
             { 
                 metadataSet.MetadataSections.Add(MetadataSection.CreateFromSchema(schema));
             } 
             else if (xmlDoc != null && MetadataSection.IsPolicyElement(xmlDoc))
             {
                 metadataSet.MetadataSections.Add(MetadataSection.CreateFromPolicy(xmlDoc, null));
             } 
             else
             { 
                 MetadataSection mexDoc = new MetadataSection(); 
                 mexDoc.Metadata = document;
                 metadataSet.MetadataSections.Add(mexDoc); 
             }
         }

         public WsdlImporter CreateDataContractSerializerImporter(MetadataSet metaData) 
         {
             Collection wsdlImportExtensions = ConfigNS.ClientSection.GetSection().Metadata.LoadWsdlImportExtensions(); 
 
             for (int i = 0; i < wsdlImportExtensions.Count; i++)
             { 
                 if (wsdlImportExtensions[i].GetType() == typeof(XmlSerializerMessageContractImporter))
                     wsdlImportExtensions.RemoveAt(i);
             }
 
             WsdlImporter importer = new WsdlImporter(metaData, null, wsdlImportExtensions);
 
             return importer; 
         }
 
         public WsdlImporter CreateXmlSerializerImporter(MetadataSet metaData)
         {
             Collection wsdlImportExtensions = ConfigNS.ClientSection.GetSection().Metadata.LoadWsdlImportExtensions();
 
             for (int i = 0; i < wsdlImportExtensions.Count; i++)
             { 
                 if (wsdlImportExtensions[i].GetType() == typeof(DataContractSerializerMessageContractImporter)) 
                     wsdlImportExtensions.RemoveAt(i);
             } 

             WsdlImporter importer = new WsdlImporter(metaData, null, wsdlImportExtensions);

             return importer; 
         }
 
         ServiceEndpointCollection ImportWsdlPortType(XmlQualifiedName portTypeQName, WsdlImporter importer) 
          {
              foreach (WsdlNS.ServiceDescription wsdl in importer.WsdlDocuments) 
              {
                  if (wsdl.TargetNamespace == portTypeQName.Namespace)
                  {
                      WsdlNS.PortType wsdlPortType = wsdl.PortTypes[portTypeQName.Name]; 
                      if (wsdlPortType != null)
                      { 
                          ServiceEndpointCollection endpoints = importer.ImportEndpoints(wsdlPortType); 
                          return endpoints;
                      } 
                  }
              }
              return new ServiceEndpointCollection();
          } 

 
 
          ComProxy IProxyCreator.CreateProxy (IntPtr outer, ref Guid riid)
          { 
               IntPtr inner = IntPtr.Zero;
               if (riid != InterfaceID.idIDispatch )
                   throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidCastException(SR.GetString(SR.NoInterface, riid)));
               if (contractDescription == null) 
               {
                   DiagnosticUtility.DebugAssert("ContractDescription should not be null at this point"); 
 
                   throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false);
               } 
               return DispatchProxy.Create (outer, contractDescription, this);

          }
 
          bool IProxyCreator.SupportsErrorInfo (ref Guid riid)
          { 
               if (riid != InterfaceID.idIDispatch ) 
                   return false;
               else 
                   return true;

          }
 
          bool IProxyCreator.SupportsDispatch ()
          { 
              return true; 
          }
 
          bool IProxyCreator.SupportsIntrinsics ()
          {
              return true;
          } 

     } 
} 

 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK