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); } } } }
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; }
/// <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; }
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 Write71_OperationInput(string n, string ns, OperationInput o, bool isNullable, bool needType) { if (o == null) { if (isNullable) { base.WriteNullTagLiteral(n, ns); } } else { if (!needType && !(o.GetType() == typeof(OperationInput))) { throw base.CreateUnknownTypeException(o); } base.WriteStartElement(n, ns, o, false, o.Namespaces); if (needType) { base.WriteXsiType("OperationInput", "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); } }