示例#1
0
        private static void EnsureSingleNamespace(WsdlNS.ServiceDescription wsdl, Dictionary <XmlQualifiedName, XmlQualifiedName> bindingReferenceChanges)
        {
            string targetNamespace = wsdl.TargetNamespace;

            foreach (WsdlNS.Binding binding in wsdl.Bindings)
            {
                if (binding.Type.Namespace != targetNamespace)
                {
                    binding.Type = new XmlQualifiedName(binding.Type.Name, targetNamespace);
                }
            }

            foreach (WsdlNS.PortType portType in wsdl.PortTypes)
            {
                foreach (WsdlNS.Operation operation in portType.Operations)
                {
                    WsdlNS.OperationInput messageInput = operation.Messages.Input;
                    if (messageInput != null && messageInput.Message.Namespace != targetNamespace)
                    {
                        messageInput.Message = new XmlQualifiedName(messageInput.Message.Name, targetNamespace);
                    }

                    WsdlNS.OperationOutput messageOutput = operation.Messages.Output;
                    if (messageOutput != null && messageOutput.Message.Namespace != targetNamespace)
                    {
                        messageOutput.Message = new XmlQualifiedName(messageOutput.Message.Name, targetNamespace);
                    }

                    foreach (WsdlNS.OperationFault fault in operation.Faults)
                    {
                        if (fault.Message.Namespace != targetNamespace)
                        {
                            fault.Message = new XmlQualifiedName(fault.Message.Name, targetNamespace);
                        }
                    }
                }
            }

            foreach (WsdlNS.Service service in wsdl.Services)
            {
                foreach (WsdlNS.Port port in service.Ports)
                {
                    XmlQualifiedName newPortBinding;
                    if (bindingReferenceChanges.TryGetValue(port.Binding, out newPortBinding))
                    {
                        port.Binding = newPortBinding;
                    }
                    else if (port.Binding.Namespace != targetNamespace)
                    {
                        port.Binding = new XmlQualifiedName(port.Binding.Name, targetNamespace);
                    }
                }
            }
        }
示例#2
0
		bool ImportBindingContent (ServiceDescription desc, TypeStubInfo typeInfo, string url, BindingInfo binfo)
		{
			serviceDescription = desc;
			
			// Look for an unused name
			
			int n=0;
			string name = binfo.Name;
			bool found;
			do
			{
				found = false;
				foreach (Binding bi in desc.Bindings)
					if (bi.Name == name) { found = true; n++; name = binfo.Name+n; break; }
			}
			while (found);
			
			// Create the binding
			
			binding = new Binding ();
			binding.Name = name;
			binding.Type = new XmlQualifiedName (binding.Name, binfo.Namespace);
			if (binfo.WebServiceBindingAttribute != null && binfo.WebServiceBindingAttribute.EmitConformanceClaims) {
				XmlDocument doc = new XmlDocument ();
				XmlElement docElement = doc.CreateElement ("wsdl", "documentation", "http://schemas.xmlsoap.org/wsdl/");
				XmlElement claimsElement = doc.CreateElement ("wsi", "Claim", "http://ws-i.org/schemas/conformanceClaim/");
				claimsElement.Attributes.Append (doc.CreateAttribute ("conformsTo")).Value = "http://ws-i.org/profiles/basic/1.1";
				docElement.AppendChild (claimsElement);
				binding.DocumentationElement = docElement;
			}
			
			portType = new PortType ();
			portType.Name = binding.Name;

			BeginClass ();

			foreach (SoapExtensionReflector reflector in extensionReflectors)
			{
				reflector.ReflectionContext = this;
				reflector.ReflectDescription ();
			}

			foreach (MethodStubInfo method in typeInfo.Methods)
			{
				methodStubInfo = method;
				
				string metBinding = ReflectMethodBinding ();
				if (typeInfo.GetBinding (metBinding) != binfo) continue;
				
				operation = new Operation ();
				operation.Name = method.OperationName;
				operation.Documentation = method.MethodAttribute.Description;

				// FIXME: SOAP 1.1 and SOAP 1.2 should share
				// the same message definitions.

				inputMessage = new Message ();
				inputMessage.Name = method.Name + ProtocolName + "In";
				ServiceDescription.Messages.Add (inputMessage);
				
				outputMessage = new Message ();
				outputMessage.Name = method.Name + ProtocolName + "Out";
				ServiceDescription.Messages.Add (outputMessage);

				OperationInput inOp = new OperationInput ();
				if (method.Name != method.OperationName) inOp.Name = method.Name;
				Operation.Messages.Add (inOp);
				inOp.Message = new XmlQualifiedName (inputMessage.Name, ServiceDescription.TargetNamespace);
				
				OperationOutput outOp = new OperationOutput ();
				if (method.Name != method.OperationName) outOp.Name = method.Name;
				Operation.Messages.Add (outOp);
				outOp.Message = new XmlQualifiedName (outputMessage.Name, ServiceDescription.TargetNamespace);
			
				portType.Operations.Add (operation);
				ImportOperationBinding ();
				
				if (!ReflectMethod ()) {
					// (It is somewhat hacky) If we don't
					// add input/output Messages, update
					// portType/input/@message and
					// porttype/output/@message.
					Message dupIn = Parent.MappedMessagesIn [method.MethodInfo];
					ServiceDescription.Messages.Remove (inputMessage);
					inOp.Message = new XmlQualifiedName (dupIn.Name, ServiceDescription.TargetNamespace);
					Message dupOut = Parent.MappedMessagesOut [method.MethodInfo];
					ServiceDescription.Messages.Remove (outputMessage);
					outOp.Message = new XmlQualifiedName (dupOut.Name, ServiceDescription.TargetNamespace);
				}

				foreach (SoapExtensionReflector reflector in extensionReflectors)
				{
					reflector.ReflectionContext = this;
					reflector.ReflectMethod ();
				}
			}
			
			EndClass ();
			
			if (portType.Operations.Count > 0)
			{
				desc.Bindings.Add (binding);
				desc.PortTypes.Add (portType);
				return true;
			}
			else
				return false;
		}
		List<IWsdlExportExtension> ExportContractInternal (ContractDescription contract)
		{
			QName qname = new QName (contract.Name, contract.Namespace);
			if (ExportedContracts.ContainsKey (qname))
				throw new ArgumentException (String.Format (
					"A ContractDescription with Namespace : {0} and Name : {1} has already been exported.", 
					contract.Namespace, contract.Name));

			WSServiceDescription sd = GetServiceDescription (contract.Namespace);

			List<IWsdlExportExtension> extensions = new List<IWsdlExportExtension> ();
			foreach (IWsdlExportExtension extn in contract.Behaviors.FindAll<IWsdlExportExtension> ())
				extensions.Add (extn);

			XmlDocument xdoc = new XmlDocument ();

			PortType ws_port = new PortType ();
			ws_port.Name = contract.Name;

			foreach (OperationDescription sm_op in contract.Operations) {
				Operation ws_op = new Operation ();
				ws_op.Name = sm_op.Name;

				foreach (MessageDescription sm_md in sm_op.Messages) {
					//OperationMessage
					OperationMessage ws_opmsg;
					WSMessage ws_msg = new WSMessage ();
					MessagePart ws_msgpart;
					if (sm_md.Direction == MessageDirection.Input) {
						ws_opmsg = new OperationInput ();
						ws_msg.Name = String.Concat (ws_port.Name, "_", ws_op.Name, "_", "InputMessage");
						ws_msgpart = ExportMessageBodyDescription (sm_md.Body, ws_op.Name, sd.TargetNamespace);
					} else {
						ws_opmsg = new OperationOutput ();
						ws_msg.Name = String.Concat (ws_port.Name, "_", ws_op.Name, "_", "OutputMessage");
						ws_msgpart = ExportMessageBodyDescription (sm_md.Body, ws_op.Name + "Response", sd.TargetNamespace);
					}
					ws_msg.Parts.Add (ws_msgpart);	

					/* FIXME: Faults */

					//Action
					XmlAttribute attr = xdoc.CreateAttribute ("wsaw", "Action", "http://www.w3.org/2006/05/addressing/wsdl");
					attr.Value = sm_md.Action;
					ws_opmsg.ExtensibleAttributes = new XmlAttribute [] { attr };
					
					//FIXME: Set .Input & .Output

					ws_opmsg.Message = new QName (ws_msg.Name, sd.TargetNamespace);
					ws_op.Messages.Add (ws_opmsg);
					sd.Messages.Add (ws_msg);
				}

				ws_port.Operations.Add (ws_op);

				foreach (IWsdlExportExtension extn in sm_op.Behaviors.FindAll<IWsdlExportExtension> ())
					extensions.Add (extn);
			}

			//Add Imports for <types
			XmlSchema xs_import = new XmlSchema ();
			xs_import.TargetNamespace = String.Concat (
					contract.Namespace, 
					contract.Namespace.EndsWith ("/") ? "" : "/",
					"Imports");
			foreach (XmlSchema schema in GeneratedXmlSchemas.Schemas ()) {
				XmlSchemaImport imp = new XmlSchemaImport ();
				imp.Namespace = schema.TargetNamespace;
				xs_import.Includes.Add (imp);
			}
			sd.Types.Schemas.Add (xs_import);

			sd.PortTypes.Add (ws_port);
			ExportedContracts [qname] = contract;

			WsdlContractConversionContext context = new WsdlContractConversionContext (contract, ws_port);
			foreach (IWsdlExportExtension extn in extensions)
				extn.ExportContract (this, context);

			return extensions;
		}
        WsdlNS.OperationMessage CreateWsdlOperationMessage(MessageDescription message)
        {
            WsdlNS.OperationMessage wsdlOperationMessage;

            if (message.Direction == MessageDirection.Input)
                wsdlOperationMessage = new WsdlNS.OperationInput();
            else
                wsdlOperationMessage = new WsdlNS.OperationOutput();

            if (!XmlName.IsNullOrEmpty(message.MessageName))
                wsdlOperationMessage.Name = message.MessageName.EncodedName;

            // consider factoring this out of wslExporter
            WSAddressingHelper.AddActionAttribute(message.Action, wsdlOperationMessage, this.PolicyVersion);
            return wsdlOperationMessage;
        }
示例#5
0
        /// <summary>
        /// Parses a MethodInfo type and generates an Wsdl Operation element and Wsdl Message element information objects.
        /// </summary>
        /// <param name="methodInfo">A method info object containing a reflected types method.</param>
        /// <param name="isCallback">A flag used to signal that this is a callback operation.</param>
        /// <param name="serviceDescription">A ServiceDescription object used to obtain a targetNamespace
        /// and store Wsdl Message element information objects.</param>
        /// <returns></returns>
        private Operation ProcessOperation(MethodInfo methodInfo, bool isCallback, ServiceDescription serviceDescription)
        {
            Operation operation = new Operation();
            Uri actionUri = null;
            Uri replyActionUri = null;
            bool isOneWay = false;
            string operationName = null;
            XmlDocument xmlDoc = new XmlDocument();

            // Look for the OperationContractAttribute
            object[] customAttributes = methodInfo.GetCustomAttributes(false);
            foreach (Attribute customAttrib in customAttributes)
            {
                string customAttribName = customAttrib.GetType().Name;
                if (customAttribName == "OperationContractAttribute" || customAttribName == "OperationContract")
                {
                    // Create in and out action attributes. If no action contract attribute is found create an action
                    // using the class namespace and operation name. If ReplyAction attribute is not found but action
                    // is use the action attribute to build the replyto attribute.
                    // Create in action uri
                    string action = (string)customAttrib.GetType().GetProperty("Action", typeof(string)).GetValue(customAttrib, null);
                    string actionNamespace = null;
                    string actionName = null;
                    if (action == null)
                        actionUri = new Uri(serviceDescription.TargetNamespace + "/" + methodInfo.Name);
                    else
                    {
                        int actionIndex = action.LastIndexOf(':');
                        actionIndex = actionIndex == -1 || actionIndex < action.LastIndexOf('/') ? action.LastIndexOf('/') : actionIndex;
                        actionNamespace = actionIndex == -1 ? action : action.Substring(0, actionIndex);
                        actionName = actionIndex == -1 ? action : action.Substring(actionIndex + 1, action.Length - (actionIndex + 1));
                        actionUri = new Uri(actionNamespace + "/" + actionName);
                    }
                    
                    // Create out action Uri
                    string replyAction = (string)customAttrib.GetType().GetProperty("ReplyAction", typeof(string)).GetValue(customAttrib, null);
                    if (replyAction == null)
                    {
                        if (action == null)
                            replyActionUri = new Uri(serviceDescription.TargetNamespace + "/" + methodInfo.Name + "Response");
                        else
                            replyActionUri = new Uri(actionNamespace + "/" + methodInfo.Name + "Response");
                    }
                    else
                    {
                        int actionIndex = replyAction.LastIndexOf(':');
                        actionIndex = actionIndex == -1 || actionIndex < replyAction.LastIndexOf('/') ? replyAction.LastIndexOf('/') : actionIndex;
                        actionNamespace = actionIndex == -1 ? replyAction : replyAction.Substring(0, actionIndex);
                        actionName = actionIndex == -1 ? replyAction : replyAction.Substring(actionIndex + 1, replyAction.Length - (actionIndex + 1));
                        replyActionUri = new Uri(actionNamespace + "/" + actionName);
                    }

                    operation.Name = operationName == null ? methodInfo.Name : operation.Name;
                    Logger.WriteLine("      Operation Name = " + operation.Name, LogLevel.Normal);

                    // Process the operations request parameters
                    ProcessOperationParams(methodInfo, operation, isCallback, serviceDescription);

                    // If this is a callback don't include an input type
                    if (!isCallback)
                    {
                        OperationInput inMessage = new OperationInput();
                        inMessage.Message = new XmlQualifiedName(methodInfo.Name + "In", serviceDescription.TargetNamespace);
                        
                        // Add the action extension attribute to the message (Wsdapi needs it to be in the operation)
                        XmlAttribute inActionAttrib = xmlDoc.CreateAttribute("wsa", "Action", "http://schemas.xmlsoap.org/ws/2004/08/addressing");
                        XmlAttribute[] inAttribs = new XmlAttribute[1];
                        inActionAttrib.Value = actionUri.ToString();
                        inAttribs.SetValue(inActionAttrib, 0);
                        inMessage.ExtensibleAttributes = inAttribs;

                        operation.Messages.Add(inMessage);

                        // If the message is a oneway, skip creating a out message
                        if (!isOneWay)
                        {
                            ProcessReturnType(methodInfo, operation, isCallback, serviceDescription);
                            OperationOutput outMessage = new OperationOutput();
                            outMessage.Message = new XmlQualifiedName(methodInfo.Name + "Out", serviceDescription.TargetNamespace);
                            
                            // Add the extension action attribute to the message (Wsdapi needs it to be in the operaiton)
                            XmlAttribute outActionAttrib = xmlDoc.CreateAttribute("wsa", "Action", "http://schemas.xmlsoap.org/ws/2004/08/addressing");
                            XmlAttribute[] outAttribs = new XmlAttribute[1];
                            outActionAttrib.Value = replyActionUri.ToString();
                            outAttribs.SetValue(outActionAttrib, 0);
                            outMessage.ExtensibleAttributes = outAttribs;
                            
                            operation.Messages.Add(outMessage);
                        }
                    }
                    // Else if this is a callback operation the method parameters become out parameter
                    else
                    {
                        OperationOutput outMessage = new OperationOutput();
                        outMessage.Message = new XmlQualifiedName(methodInfo.Name + "Out", serviceDescription.TargetNamespace);

                        // Add the extension action attribute to the message (Wsdapi needs it to be in the operaiton)
                        XmlAttribute actionAttrib = xmlDoc.CreateAttribute("wsa", "Action", "http://schemas.xmlsoap.org/ws/2004/08/addressing");
                        XmlAttribute[] attribs = new XmlAttribute[1];
                        actionAttrib.Value = actionUri.ToString();
                        attribs.SetValue(actionAttrib, 0);
                        outMessage.ExtensibleAttributes = attribs;

                        operation.Messages.Add(outMessage);
                    }

                    return operation;
                }
            }
            return null;
        }
示例#6
0
        bool ImportBindingContent(ServiceDescription desc, TypeStubInfo typeInfo, string url, BindingInfo binfo)
        {
            serviceDescription = desc;

            // Look for an unused name

            int    n    = 0;
            string name = binfo.Name;
            bool   found;

            do
            {
                found = false;
                foreach (Binding bi in desc.Bindings)
                {
                    if (bi.Name == name)
                    {
                        found = true; n++; name = binfo.Name + n; break;
                    }
                }
            }while (found);

            // Create the binding

            binding      = new Binding();
            binding.Name = name;
            binding.Type = new XmlQualifiedName(binding.Name, binfo.Namespace);
#if NET_2_0
            if (binfo.WebServiceBindingAttribute != null && binfo.WebServiceBindingAttribute.EmitConformanceClaims)
            {
                XmlDocument doc           = new XmlDocument();
                XmlElement  docElement    = doc.CreateElement("wsdl", "documentation", "http://schemas.xmlsoap.org/wsdl/");
                XmlElement  claimsElement = doc.CreateElement("wsi", "Claim", "http://ws-i.org/schemas/conformanceClaim/");
                claimsElement.Attributes.Append(doc.CreateAttribute("conformsTo")).Value = "http://ws-i.org/profiles/basic/1.1";
                docElement.AppendChild(claimsElement);
                binding.DocumentationElement = docElement;
            }
#endif

            portType      = new PortType();
            portType.Name = binding.Name;

            BeginClass();

            foreach (SoapExtensionReflector reflector in extensionReflectors)
            {
                reflector.ReflectionContext = this;
                reflector.ReflectDescription();
            }

            foreach (MethodStubInfo method in typeInfo.Methods)
            {
                methodStubInfo = method;

                string metBinding = ReflectMethodBinding();
                if (typeInfo.GetBinding(metBinding) != binfo)
                {
                    continue;
                }

                operation               = new Operation();
                operation.Name          = method.OperationName;
                operation.Documentation = method.MethodAttribute.Description;

                // FIXME: SOAP 1.1 and SOAP 1.2 should share
                // the same message definitions.

                inputMessage      = new Message();
                inputMessage.Name = method.Name + ProtocolName + "In";
                ServiceDescription.Messages.Add(inputMessage);

                outputMessage      = new Message();
                outputMessage.Name = method.Name + ProtocolName + "Out";
                ServiceDescription.Messages.Add(outputMessage);

                OperationInput inOp = new OperationInput();
                if (method.Name != method.OperationName)
                {
                    inOp.Name = method.Name;
                }
                Operation.Messages.Add(inOp);
                inOp.Message = new XmlQualifiedName(inputMessage.Name, ServiceDescription.TargetNamespace);

                OperationOutput outOp = new OperationOutput();
                if (method.Name != method.OperationName)
                {
                    outOp.Name = method.Name;
                }
                Operation.Messages.Add(outOp);
                outOp.Message = new XmlQualifiedName(outputMessage.Name, ServiceDescription.TargetNamespace);

                portType.Operations.Add(operation);
                ImportOperationBinding();

                if (!ReflectMethod())
                {
#if NET_2_0
                    // (It is somewhat hacky) If we don't
                    // add input/output Messages, update
                    // portType/input/@message and
                    // porttype/output/@message.
                    Message dupIn = Parent.MappedMessagesIn [method.MethodInfo];
                    ServiceDescription.Messages.Remove(inputMessage);
                    inOp.Message = new XmlQualifiedName(dupIn.Name, ServiceDescription.TargetNamespace);
                    Message dupOut = Parent.MappedMessagesOut [method.MethodInfo];
                    ServiceDescription.Messages.Remove(outputMessage);
                    outOp.Message = new XmlQualifiedName(dupOut.Name, ServiceDescription.TargetNamespace);
#endif
                }

                foreach (SoapExtensionReflector reflector in extensionReflectors)
                {
                    reflector.ReflectionContext = this;
                    reflector.ReflectMethod();
                }
            }

            EndClass();

            if (portType.Operations.Count > 0)
            {
                desc.Bindings.Add(binding);
                desc.PortTypes.Add(portType);
                return(true);
            }
            else
            {
                return(false);
            }
        }
        /// <summary>
        /// Generates the WSDL file for a specified <see cref="InterfaceContract"/>.
        /// </summary>
        /// <param name="serviceInterfaceContract">
        /// <see cref="InterfaceContract"/> to use for the WSDL generation.
        /// </param>
        /// <param name="wsdlSaveLocation">Location to save the generated WSDL file.</param>
        /// <param name="xmlComment">XML comment to add to the top of the WSDL file.</param>
        /// <param name="wsdlLocation">Path of an existing WSDL file to overwrite with the generated 
        /// WSDL file.</param>
        /// <returns>The path of the WSDL file generated.</returns>
        /// <remarks>
        /// This methods loads the information, it receive in a <see cref="InterfaceContract"/> to
        /// a <see cref="System.Web.Services.Description.ServiceDescription"/> class, which is later 
        /// used to generate the WSDL file. The loading process takes place in several steps. <br></br>
        /// 1. Load the basic meta data from <see cref="InterfaceContract"/>.<br></br>
        /// 2. Load the schema imports in the <see cref="SchemaImports"/> collection.<br></br>
        /// 3. Load the messages in <see cref="OperationsCollection"/>.<br></br>
        /// 4. Create the WSDL Port Type.<br></br>
        /// 5. Add each operation and it's corresponding in/out messages to the Port Type.<br></br>
        /// 6. Create a WSDL Binding section and add OperationBinding for each operation.<br></br>
        /// 7. Generate the WSDL 'service' tags if required.<br></br>
        /// 8. Finally write the file to the output stream.<br></br>
        /// 
        /// This method generates <see cref="WsdlGenerationException"/> exception, if it fails to create the WSDL file.
        /// If a file is specified to overwrite with the new file, the original file is restored in case of
        /// a failure.
        /// </remarks>
        public static string GenerateWsdl(InterfaceContract serviceInterfaceContract,
            string wsdlSaveLocation, string xmlComment, string wsdlLocation)
        {
            System.Web.Services.Description.ServiceDescription desc = null;

            string serviceAttributeName = "";
            string bindingName = "";
            string serviceName = "";
            string portTypeName = "";

            // Load the existing WSDL if one specified.
            if (wsdlLocation != null)
            {
                #region Round-tripping

                desc = System.Web.Services.Description.ServiceDescription.Read(wsdlLocation);

                // Read the existing name values.
                serviceAttributeName = desc.Name;
                bindingName = desc.Bindings[0].Name;
                portTypeName = desc.PortTypes[0].Name;

                // Check whether we have a service element and save it's name for the 
                // future use.
                if (desc.Services.Count > 0)
                {
                    serviceName = desc.Services[0].Name;
                }
                else
                {
                    serviceName = serviceInterfaceContract.ServiceName + "Port"; ;
                }

                // Check for the place which has the Service name and assign the new value 
                // appropriatly.			
                if (serviceAttributeName != null && serviceAttributeName != "")
                {
                    serviceAttributeName = serviceInterfaceContract.ServiceName;
                }
                else if (serviceName != null && serviceName != "")
                {
                    // If the user has selected to remove the service element, 
                    // use the service name in the attribute by default.
                    if (serviceInterfaceContract.NeedsServiceElement)
                    {
                        serviceName = serviceInterfaceContract.ServiceName;
                    }
                    else
                    {
                        serviceAttributeName = serviceInterfaceContract.ServiceName;
                    }
                }
                else if (bindingName != null && bindingName != "")
                {
                    bindingName = serviceInterfaceContract.ServiceName;
                }

                // Clear the service description. But do not clear the types definitions.
                desc.Extensions.Clear();
                desc.Bindings.Clear();
                desc.Documentation = "";
                desc.Imports.Clear();
                desc.Messages.Clear();
                desc.PortTypes.Clear();
                desc.RetrievalUrl = "";

                if (desc.ServiceDescriptions != null)
                {
                    desc.ServiceDescriptions.Clear();
                }

                if (!serviceInterfaceContract.NeedsServiceElement)
                {
                    desc.Services.Clear();
                }
                #endregion
            }
            else
            {
                #region New WSDL

                desc = new System.Web.Services.Description.ServiceDescription();

                // Create the default names.
                serviceAttributeName = serviceInterfaceContract.ServiceName;
                bindingName = serviceInterfaceContract.ServiceName;
                portTypeName = serviceInterfaceContract.ServiceName + "Interface";
                serviceName = serviceInterfaceContract.ServiceName + "Port";

                #endregion
            }

            #region Load the basic meta data.
            if (serviceAttributeName != null && serviceAttributeName != "")
            {
                desc.Name = serviceAttributeName;
            }
            desc.TargetNamespace = serviceInterfaceContract.ServiceNamespace;
            desc.Documentation = serviceInterfaceContract.ServiceDocumentation;
            #endregion

            #region Load the schema imports.

            XmlSchema typesSchema = null;

            // Are we round-tripping? Then we have to access the existing types 
            // section.
            // Otherwise we just initialize a new XmlSchema for types.
            if (wsdlLocation != null)
            {
                typesSchema = desc.Types.Schemas[desc.TargetNamespace];
                // if we don't have a types section belonging to the same namespace as service description
                // we take the first types section available.                
                if (typesSchema == null)
                {
                    typesSchema = desc.Types.Schemas[0];
                }
                // Remove the includes. We gonna re-add them later in this operation.
                typesSchema.Includes.Clear();
            }
            else
            {
                typesSchema = new XmlSchema();
            }

            // Add imports to the types section resolved above.
            foreach (SchemaImport import in serviceInterfaceContract.Imports)
            {
                XmlSchemaExternal importedSchema = null;
                if (import.SchemaNamespace == null || import.SchemaNamespace == "")
                {
                    importedSchema = new XmlSchemaInclude();
                }
                else
                {
                    importedSchema = new XmlSchemaImport();
                    ((XmlSchemaImport)importedSchema).Namespace = import.SchemaNamespace;
                }
                if (serviceInterfaceContract.UseAlternateLocationForImports)
                {
                    importedSchema.SchemaLocation = import.AlternateLocation;
                }
                else
                {
                    importedSchema.SchemaLocation = import.SchemaLocation;
                }
                typesSchema.Includes.Add(importedSchema);
            }

            // If we are not round-tripping we have to link the types schema we just created to 
            // the service description.
            if (wsdlLocation == null)
            {
                // Finally add the type schema to the ServiceDescription.Types.Schemas collection.
                desc.Types.Schemas.Add(typesSchema);
            }

            #endregion

            #region Load the messages in all the operations

            MessageCollection msgs = desc.Messages;

            foreach (Operation op in serviceInterfaceContract.OperationsCollection)
            {
                foreach (Message msg in op.MessagesCollection)
                {
                    FxMessage tempMsg = new FxMessage();
                    tempMsg.Name = msg.Name;
                    tempMsg.Documentation = msg.Documentation;

                    MessagePart msgPart = new MessagePart();
                    msgPart.Name = Constants.DefaultMessagePartName;
                    msgPart.Element = new XmlQualifiedName(msg.Element.ElementName,
                            msg.Element.ElementNamespace);
                    tempMsg.Parts.Add(msgPart);

                    msgs.Add(tempMsg);
                }

				foreach (Message msg in op.Faults)
				{
					Message messageName = msg;
					if (msgs.OfType<FxMessage>().Any(m => m.Name == messageName.Name)) continue;

					FxMessage tempMsg = new FxMessage();
					tempMsg.Name = msg.Name;
					tempMsg.Documentation = msg.Documentation;

					MessagePart msgPart = new MessagePart();
					msgPart.Name = Constants.FaultMessagePartName;
					msgPart.Element = new XmlQualifiedName(msg.Element.ElementName, msg.Element.ElementNamespace);
					tempMsg.Parts.Add(msgPart);

					msgs.Add(tempMsg);
				}
            }

            #endregion

            #region Create the Port Type

            PortTypeCollection portTypes = desc.PortTypes;
            PortType portType = new PortType();
            portType.Name = portTypeName;
            portType.Documentation = serviceInterfaceContract.ServiceDocumentation;

            // Add each operation and it's corresponding in/out messages to the WSDL Port Type.
            foreach (Operation op in serviceInterfaceContract.OperationsCollection)
            {
                FxOperation tempOperation = new FxOperation();
                tempOperation.Name = op.Name;
                tempOperation.Documentation = op.Documentation;
                int i = 0;

                OperationInput operationInput = new OperationInput();
                operationInput.Message = new XmlQualifiedName(op.MessagesCollection[i].Name, desc.TargetNamespace);

                tempOperation.Messages.Add(operationInput);

                if (op.Mep == Mep.RequestResponse)
                {
                    OperationOutput operationOutput = new OperationOutput();
                    operationOutput.Message = new XmlQualifiedName(op.MessagesCollection[i + 1].Name, desc.TargetNamespace);

                    tempOperation.Messages.Add(operationOutput);
                }

				foreach (Message fault in op.Faults)
				{
					OperationFault operationFault = new OperationFault();
					operationFault.Name = fault.Name;
					operationFault.Message = new XmlQualifiedName(fault.Name, desc.TargetNamespace);
					tempOperation.Faults.Add(operationFault);
				}
				
                portType.Operations.Add(tempOperation);
                i++;
            }

            portTypes.Add(portType);

            #endregion

            // Here we have a list of WCF endpoints.
            // Currently we populate this list with only two endpoints that has default
            // BasicHttpBinding and default NetTcpBinding.
            List<ServiceEndpoint> endpoints = new List<ServiceEndpoint>();

            BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
            endpoints.Add(ServiceEndpointFactory<IDummyContract>.CreateServiceEndpoint(basicHttpBinding));

            // BDS (10/22/2007): Commented out the TCP binding generation as we are not going to support this feature
            // in this version.
            //NetTcpBinding netTcpBinding = new NetTcpBinding();
            //endpoints.Add(ServiceEndpointFactory<IDummyContract>.CreateServiceEndpoint(netTcpBinding));

            // Now, for each endpoint we have to create a binding in our service description.
            foreach (ServiceEndpoint endpoint in endpoints)
            {
                // Create a WSDL BindingCollection.
                BindingCollection bindings = desc.Bindings;
                System.Web.Services.Description.Binding binding = new System.Web.Services.Description.Binding();
                binding.Name = endpoint.Name.Replace(Constants.InternalContractName, portTypeName);
                binding.Type = new XmlQualifiedName(portType.Name, desc.TargetNamespace);

                // Create Operation binding for each operation and add it the the BindingCollection.
                foreach (Operation op in serviceInterfaceContract.OperationsCollection)
                {
                    // SOAP 1.1 Operation bindings.
                    OperationBinding operationBinding1 = new OperationBinding();
                    operationBinding1.Name = op.Name;

                    InputBinding inputBinding1 = new InputBinding();
                    object bodyBindingExtension = GetSoapBodyBinding(endpoint.Binding);
                    if (bodyBindingExtension != null)
                    {
                        inputBinding1.Extensions.Add(bodyBindingExtension);
                    }
                    operationBinding1.Input = inputBinding1;

					// Faults.
                	foreach (Message fault in op.Faults)
                	{
                		FaultBinding faultBinding = new FaultBinding();
                		faultBinding.Name = fault.Name;

						SoapFaultBinding faultBindingExtension = GetFaultBodyBinding(endpoint.Binding);
						if (faultBindingExtension != null)
						{
							faultBindingExtension.Name = fault.Name;
							faultBinding.Extensions.Add(faultBindingExtension);
						}

                		operationBinding1.Faults.Add(faultBinding);
                	}

                    // Input message.
                    // Look up the message headers for each Message and add them to the current binding.
                    foreach (MessageHeader inHeader in op.MessagesCollection[0].HeadersCollection)
                    {
                        object headerBindingExtension = GetSoapHeaderBinding(endpoint.Binding, inHeader.Message, desc.TargetNamespace);
                        if (headerBindingExtension != null)
                        {
                            inputBinding1.Extensions.Add(headerBindingExtension);
                        }
                    }

                    if (op.Mep == Mep.RequestResponse)
                    {
                        // Output message.
                        OutputBinding outputBinding1 = new OutputBinding();
                        object responseBodyBindingExtension = GetSoapBodyBinding(endpoint.Binding);
                        if (responseBodyBindingExtension != null)
                        {
                            outputBinding1.Extensions.Add(responseBodyBindingExtension);
                        }
                        operationBinding1.Output = outputBinding1;

                        // Look up the message headers for each Message and add them to the current binding. 
                        foreach (MessageHeader outHeader in op.MessagesCollection[1].HeadersCollection)
                        {
                            object headerBindingExtension = GetSoapHeaderBinding(endpoint.Binding, outHeader.Message, desc.TargetNamespace);
                            if (headerBindingExtension != null)
                            {
                                outputBinding1.Extensions.Add(headerBindingExtension);
                            }
                        }
                    }

                    string action = desc.TargetNamespace + ":" + op.Input.Name;
                    object operationBindingExtension = GetSoapOperationBinding(endpoint.Binding, action);
                    if (operationBindingExtension != null)
                    {
                        operationBinding1.Extensions.Add(operationBindingExtension);
                    }

                    binding.Operations.Add(operationBinding1);
                    // End of SOAP 1.1 operation bindings.                    
                }

                object soapBindingExtension = GetSoapBinding(endpoint.Binding);
                if (soapBindingExtension != null)
                {
                    binding.Extensions.Add(soapBindingExtension);
                }
                bindings.Add(binding);
            }

            // Generate <service> element optionally - sometimes necessary for interop reasons
            if (serviceInterfaceContract.NeedsServiceElement)
            {
                Service defaultService = null;
                if (wsdlLocation == null || desc.Services.Count == 0)
                {
                    // Create a new service element.
                    defaultService = new Service();
                    defaultService.Name = serviceName;
                    foreach (ServiceEndpoint endpoint in endpoints)
                    {
                        if (endpoint.Binding.MessageVersion.Envelope == EnvelopeVersion.Soap11)
                        {
                            Port defaultPort = new Port();
                            defaultPort.Name = serviceInterfaceContract.ServiceName + "Port";
                            defaultPort.Binding = new XmlQualifiedName(endpoint.Name.Replace(Constants.InternalContractName, portTypeName), desc.TargetNamespace);
                            SoapAddressBinding defaultSoapAddressBinding = new SoapAddressBinding();
                            defaultSoapAddressBinding.Location = GetDefaultEndpoint(endpoint.Binding, serviceInterfaceContract.ServiceName);
                            defaultPort.Extensions.Add(defaultSoapAddressBinding);
                            defaultService.Ports.Add(defaultPort);
                        }
                        else if (endpoint.Binding.MessageVersion.Envelope == EnvelopeVersion.Soap12)
                        {
                            Port soap12Port = new Port();
                            soap12Port.Name = serviceInterfaceContract.ServiceName + "SOAP12Port";
                            soap12Port.Binding = new XmlQualifiedName(endpoint.Name.Replace(Constants.InternalContractName, portTypeName), desc.TargetNamespace);
                            Soap12AddressBinding soap12AddressBinding = new Soap12AddressBinding();
                            soap12AddressBinding.Location = GetDefaultEndpoint(endpoint.Binding, serviceInterfaceContract.ServiceName);
                            soap12Port.Extensions.Add(soap12AddressBinding);
                            defaultService.Ports.Add(soap12Port);
                        }                        
                    }
                    
                    desc.Services.Add(defaultService);                    
                }
                else
                {
                    defaultService = desc.Services[0];
                    defaultService.Name = serviceName;
                }
            }

            // Generate the WSDL file.
            string fileName = string.Empty;
            string bkFileName = string.Empty;

            // Overwrite the existing file if one specified.
            if (wsdlLocation == null)
            {
                fileName = wsdlSaveLocation + @"\" + serviceInterfaceContract.ServiceName + ".wsdl";
            }
            else
            {
                fileName = wsdlLocation;
            }

            // Backup existing file before proceeding.
            if (File.Exists(fileName))
            {
                int index = 1;
                // Create the backup file name. 
                // See whether the generated backup file name is already taken by an existing file and 
                // generate a new file name. 
                while (File.Exists(fileName + "." + index.ToString()))
                {
                    index++;
                }
                bkFileName = fileName + "." + index.ToString();

                // Backup the file.
                try
                {
                    File.Copy(fileName, bkFileName);
                }
                catch (Exception ex)
                {
                    throw new WsdlGenerationException("An error occured while trying to generate a WSDL. Failed to backup the existing WSDL file.", ex);
                }
            }

            StreamWriter writer1 = new StreamWriter(fileName);
            try
            {
                XmlTextWriter writer11 = new XmlTextWriter(writer1);

                writer11.Formatting = Formatting.Indented;
                writer11.Indentation = 2;
                writer11.WriteComment(xmlComment);
                // BDS: Added a new comment line with the date time of WSDL file.
                CultureInfo ci = new CultureInfo("en-US");
                writer11.WriteComment(DateTime.Now.ToString("dddd", ci) + ", " + DateTime.Now.ToString("dd-MM-yyyy - hh:mm tt", ci));

                XmlSerializer serializer1 = System.Web.Services.Description.ServiceDescription.Serializer;
                XmlSerializerNamespaces nsSer = new XmlSerializerNamespaces();
                nsSer.Add("soap", "http://schemas.xmlsoap.org/wsdl/soap/");
                nsSer.Add("soap12", "http://schemas.xmlsoap.org/wsdl/soap12/");
                nsSer.Add("xsd", "http://www.w3.org/2001/XMLSchema");
                nsSer.Add("tns", desc.TargetNamespace);

                // Add the imported namespaces to the WSDL <description> element.
                for (int importIndex = 0; importIndex < serviceInterfaceContract.Imports.Count;
                    importIndex++)
                {
                    if (serviceInterfaceContract.Imports[importIndex].SchemaNamespace != null &&
                        serviceInterfaceContract.Imports[importIndex].SchemaNamespace != "")
                    {
                        nsSer.Add("import" + importIndex.ToString(),
                                  serviceInterfaceContract.Imports[importIndex].SchemaNamespace);
                    }
                }
                // 

                // Finally write the file to the output stram.
                serializer1.Serialize(writer11, desc, nsSer);

                // Close the stream and delete the backupfile.
                writer1.Close();
                if (bkFileName != string.Empty)
                {
                    File.Delete(bkFileName);
                }

                WsdlWorkshop workshop = new WsdlWorkshop(endpoints, fileName, portTypeName);
                workshop.BuildWsdl();
                return fileName;
            }
            catch (Exception ex)
            {
                writer1.Close();
                string message = ex.Message;
                if (ex.InnerException != null)
                {
                    message += ex.InnerException.Message;
                }

                // Restore the original file.
                if (bkFileName != string.Empty)
                {
                    try
                    {
                        File.Copy(bkFileName, fileName, true);
                        File.Delete(bkFileName);
                    }
                    catch
                    {
                        throw new WsdlGenerationException(
                            message + "\nFailed to restore the original file.");
                    }
                }
                else if (File.Exists(fileName))
                {
                    File.Delete(fileName);
                }

                throw new WsdlGenerationException(
                    message, ex);
            }
        }
		bool ImportBindingContent (ServiceDescription desc, TypeStubInfo typeInfo, string url, BindingInfo binfo)
		{
			serviceDescription = desc;
			
			// Look for an unused name
			
			int n=0;
			string name = binfo.Name;
			bool found;
			do
			{
				found = false;
				foreach (Binding bi in desc.Bindings)
					if (bi.Name == name) { found = true; n++; name = binfo.Name+n; break; }
			}
			while (found);
			
			// Create the binding
			
			binding = new Binding ();
			binding.Name = name;
			binding.Type = new XmlQualifiedName (binding.Name, binfo.Namespace);
			
			portType = new PortType ();
			portType.Name = binding.Name;

			BeginClass ();
			
			foreach (MethodStubInfo method in typeInfo.Methods)
			{
				methodStubInfo = method;
				
				string metBinding = ReflectMethodBinding ();
				if (typeInfo.GetBinding (metBinding) != binfo) continue;
				
				operation = new Operation ();
				operation.Name = method.OperationName;
				operation.Documentation = method.MethodAttribute.Description;
				
				inputMessage = new Message ();
				inputMessage.Name = method.Name + ProtocolName + "In";
				ServiceDescription.Messages.Add (inputMessage);
				
				outputMessage = new Message ();
				outputMessage.Name = method.Name + ProtocolName + "Out";
				ServiceDescription.Messages.Add (outputMessage);

				OperationInput inOp = new OperationInput ();
				if (method.Name != method.OperationName) inOp.Name = method.Name;
				Operation.Messages.Add (inOp);
				inOp.Message = new XmlQualifiedName (inputMessage.Name, ServiceDescription.TargetNamespace);
				
				OperationOutput outOp = new OperationOutput ();
				if (method.Name != method.OperationName) outOp.Name = method.Name;
				Operation.Messages.Add (outOp);
				outOp.Message = new XmlQualifiedName (outputMessage.Name, ServiceDescription.TargetNamespace);
			
				portType.Operations.Add (operation);
				ImportOperationBinding ();
				
				ReflectMethod ();
				
				foreach (SoapExtensionReflector reflector in extensionReflectors)
				{
					reflector.ReflectionContext = this;
					reflector.ReflectMethod ();
				}
			}
			
			EndClass ();
			
			if (portType.Operations.Count > 0)
			{
				desc.Bindings.Add (binding);
				desc.PortTypes.Add (portType);
				return true;
			}
			else
				return false;
		}
 private OperationMessage CreateWsdlOperationMessage(MessageDescription message)
 {
     OperationMessage message2;
     if (message.Direction == MessageDirection.Input)
     {
         message2 = new OperationInput();
     }
     else
     {
         message2 = new OperationOutput();
     }
     if (!System.ServiceModel.Description.XmlName.IsNullOrEmpty(message.MessageName))
     {
         message2.Name = message.MessageName.EncodedName;
     }
     WSAddressingHelper.AddActionAttribute(message.Action, message2, base.PolicyVersion);
     return message2;
 }
        private static PortType ConstructPortTypes(InterfaceContract serviceInterfaceContract, System.Web.Services.Description.ServiceDescription desc, string portTypeName)
        {
            PortTypeCollection portTypes = desc.PortTypes;
            PortType portType = new PortType();
            portType.Name = portTypeName;
            portType.Documentation = serviceInterfaceContract.ServiceDocumentation;

            // Add each operation and it's corresponding in/out messages to the WSDL Port Type.
            foreach (Operation op in serviceInterfaceContract.Operations)
            {
                FxOperation tempOperation = new FxOperation();
                tempOperation.Name = op.Name;
                tempOperation.Documentation = op.Documentation;
                int i = 0;

                OperationInput operationInput = new OperationInput();
                operationInput.Message = new XmlQualifiedName(op.MessagesCollection[i].Name, desc.TargetNamespace);

                tempOperation.Messages.Add(operationInput);

                if (op.Mep == Mep.RequestResponse)
                {
                    OperationOutput operationOutput = new OperationOutput();
                    operationOutput.Message = new XmlQualifiedName(op.MessagesCollection[i + 1].Name, desc.TargetNamespace);

                    tempOperation.Messages.Add(operationOutput);
                }

                portType.Operations.Add(tempOperation);
                i++;
            }

            portTypes.Add(portType);
            return portType;
        }
 private void Write72_OperationOutput(string n, string ns, OperationOutput o, bool isNullable, bool needType)
 {
     if (o == null)
     {
         if (isNullable)
         {
             base.WriteNullTagLiteral(n, ns);
         }
     }
     else
     {
         if (!needType && !(o.GetType() == typeof(OperationOutput)))
         {
             throw base.CreateUnknownTypeException(o);
         }
         base.WriteStartElement(n, ns, o, false, o.Namespaces);
         if (needType)
         {
             base.WriteXsiType("OperationOutput", "http://schemas.xmlsoap.org/wsdl/");
         }
         XmlAttribute[] extensibleAttributes = o.ExtensibleAttributes;
         if (extensibleAttributes != null)
         {
             for (int i = 0; i < extensibleAttributes.Length; i++)
             {
                 XmlAttribute node = extensibleAttributes[i];
                 base.WriteXmlAttribute(node, o);
             }
         }
         base.WriteAttribute("name", "", o.Name);
         base.WriteAttribute("message", "", base.FromXmlQualifiedName(o.Message));
         if ((o.DocumentationElement == null) && (o.DocumentationElement != null))
         {
             throw base.CreateInvalidAnyTypeException(o.DocumentationElement);
         }
         base.WriteElementLiteral(o.DocumentationElement, "documentation", "http://schemas.xmlsoap.org/wsdl/", false, true);
         ServiceDescriptionFormatExtensionCollection extensions = o.Extensions;
         if (extensions != null)
         {
             for (int j = 0; j < extensions.Count; j++)
             {
                 if (!(extensions[j] is XmlNode) && (extensions[j] != null))
                 {
                     throw base.CreateInvalidAnyTypeException(extensions[j]);
                 }
                 base.WriteElementLiteral((XmlNode) extensions[j], "", null, false, true);
             }
         }
         base.WriteEndElement(o);
     }
 }