public Message () { #if !NET_2_0 name = String.Empty; #endif parts = new MessagePartCollection (this); serviceDescription = null; }
public Message() { #if !NET_2_0 name = String.Empty; #endif #if NET_2_0 extensions = new ServiceDescriptionFormatExtensionCollection(this); #endif parts = new MessagePartCollection(this); serviceDescription = null; }
public Message () { #if !NET_2_0 name = String.Empty; #endif #if NET_2_0 extensions = new ServiceDescriptionFormatExtensionCollection (this); #endif parts = new MessagePartCollection (this); serviceDescription = null; }
public Message () { extensions = new ServiceDescriptionFormatExtensionCollection (this); parts = new MessagePartCollection (this); serviceDescription = null; }
/// <summary> /// Parses a Wsdl message parts collection and builds an array of required message elements and or types. /// </summary> /// <param name="messageParts">A collection of message parts.</param> /// <returns>An array list containing elements and types specified in a Wsdl message parts collection.</returns> private ArrayList GetMessageSchemaDefinitions(MessagePartCollection messageParts) { int elementCount = 0; // Used to validate message parts int typeCount = 0; // Used to validate message parts ArrayList schemaDefs = new ArrayList(); // When complete contains reference to schema elements for the parts // For each input message part find the schema element or type and add it to the inputSchemaParams hash foreach (MessagePart part in messageParts) { // This part defines an element if (part.Element.IsEmpty == false && part.Type.IsEmpty == true) { // Make sure Element and Type parts are not mixed if (typeCount > 0) throw new XmlException("Invalid wsdl:message part. All parts of message in operation must either contain type or element."); XmlSchemaElement element = null; if ((element = CodeGenUtils.FindSchemaElement(m_svcDesc, part.Element.Name, part.Element.Namespace)) != null) { schemaDefs.Add((XmlSchemaElement)element); ++elementCount; } else { throw new XmlException("Missing element specified." + "\n Message name : " + part.Message.Name + "\n Message part name: " + part.Name + "\n Type name : " + part.Type.Name + "\n Type namespace : " + part.Type.Namespace + "\n Element name : " + part.Element.Name + "\n Element namespace: " + part.Element.Namespace ); } } // This part defines a type else if (part.Element.IsEmpty == true && part.Type.IsEmpty == false) { // Make sure Element and Type parts are not mixed if (elementCount > 0) throw new XmlException("Invalid wsdl:message part. All parts of message in operation must either contain type or element."); XmlSchemaType type = null; if ((type = CodeGenUtils.FindSchemaType(m_svcDesc, part.Type.Name, part.Type.Namespace)) != null) { schemaDefs.Add((XmlSchemaType)type); ++typeCount; } else { XmlSchemaType typ = XmlSchemaType.GetBuiltInSimpleType(part.Type); if (typ != null) { schemaDefs.Add(typ); ++typeCount; } else { throw new XmlException("Missing type specified. Message name: " + part.Message.Name + " Message part name: " + part.Name + " Type name: " + part.Type.Name); } } } } if (elementCount == 0 && typeCount == 0) return null; else return schemaDefs; }
/// <summary> /// For a given operation, generates a data contract for each element or type used by the operation. /// </summary> /// <param name="operation">A port type operation.</param> /// <param name="inputMessageParts">A collection of input message parts used by this operation.</param> /// <param name="outputMessageParts">A collection of output message parts used by this operation.</param> /// <param name="codeNs">The contracts code namespace.</param> private void GenerateTypeContracts(Operation operation, MessagePartCollection inputMessageParts, MessagePartCollection outputMessageParts) { ArrayList inputMessageTypes = null; ArrayList outputMessageTypes = null; if (inputMessageParts != null) inputMessageTypes = GetMessageSchemaDefinitions(inputMessageParts); if (outputMessageParts != null) outputMessageTypes = GetMessageSchemaDefinitions(outputMessageParts); // If input or output message parts are found generate DataContracts and DataContractSerializers if (inputMessageTypes != null) { m_dcCodeGen.GenerateContracts(operation.Messages.Input, inputMessageParts, inputMessageTypes); } if (outputMessageTypes != null) { m_dcCodeGen.GenerateContracts(operation.Messages.Output, outputMessageParts, outputMessageTypes); } }
/// <summary> /// Search and returns the type mapping between method parameters/return value /// and the element parts of a literal-use SOAP message. /// </summary> private XmlMembersMapping GetMembersMapping(string messageName, MessagePartCollection messageParts, SoapBodyBinding soapBodyBinding, SoapBindingStyle soapBindingStyle) { if (soapBindingStyle == SoapBindingStyle.Rpc) { SoapSchemaMember[] soapSchemaMembers = new SoapSchemaMember[messageParts.Count]; for (int i = 0; i < messageParts.Count; i++) { SoapSchemaMember ssm = new SoapSchemaMember(); ssm.MemberName = messageParts[i].Name; ssm.MemberType = messageParts[i].Type; soapSchemaMembers[i] = ssm; } return this.schemaImporter.ImportMembersMapping(messageName, soapBodyBinding.Namespace, soapSchemaMembers); } else { return this.schemaImporter.ImportMembersMapping(messageParts[0].Element); } }
/// <summary> /// For a given wsdl service operation, generate a data contract and data contract serializer for /// each element used by the operation. /// </summary> /// <param name="operationMessage">A OperationMessage type containing an OperationInput or OperationOutput type.</param> /// <param name="messageParts">A collection of message parts used by the operation.</param> /// <param name="messageTypes">An arraylist of message elements and or types used by the operation.</param> public void GenerateContracts(OperationMessage operationMessage, MessagePartCollection messageParts, ArrayList messageTypes) { // If style = document and use = literal // Doc/Lit must have no parts or 1 to n elements if (CodeGenUtils.IsDocumentLiteral(operationMessage)) { // Document literal parts can only contain element references. Do a quick check. for (int i = 0; i < messageTypes.Count; ++i) if (!(messageTypes[0] is XmlSchemaElement)) throw new XmlException("Invalid wsdl:message element: " + ((XmlSchemaType)messageTypes[0]).Name + ". Document/Literal message parts must contain element attributes or no attributes."); CodeTypeDeclaration codeType = new CodeTypeDeclaration(); // Check for wrapped style bool isWrapped = false; if (messageParts != null && messageParts.Count > 0 && CodeGenUtils.IsWrapped(messageParts[0])) isWrapped = true; // If this is wrapped and has more than one message part throw if (isWrapped && messageParts.Count > 1) throw new XmlException("Invalid number of message parts for document/literal/wrapped message \"" + operationMessage.Message.Name + "\"."); // If wrapped process single element. For now assume as long as there is one part this is wrapped. if (isWrapped || messageParts.Count == 1) { XmlSchemaElement element = (XmlSchemaElement)messageTypes[0]; CodeNamespace codeNs = CodeGenUtils.GetDotNetNamespace(m_codeNamespaces, element.QualifiedName.Namespace); BuildElementType(element, codeType); } else { // If the WS-I compliance flag is set document/literal can have at most one // message part so throw if we get here if (m_wsiCompliant) throw new XmlException("Invalid number of message parts for WS-I compliant document/literal message \"" + operationMessage.Message.Name + "\"."); // To simplify parameter passing to and from serailizers, like Rpc/Literal, seperate doc/lit // element parts (parameters) are wrapped in an object. This will not affect the format of the // actual XML messages, it will only affect parameters and return types exchnged by the // serializers and implementation contracts. // Generate Document style contracts GenerateWrappedContracts(BindingStyle.Document, operationMessage, messageParts, messageTypes); } } // Else this is an rpc/literal message else { if (!m_rpcStyleSupport) throw new XmlException("Rpc binding style is not supported. Operation = \"" + operationMessage.Operation.Name + "\"."); // For rpc literal parts can only contain type references. Do a quick check. for (int i = 0; i < messageTypes.Count; ++i) if (messageTypes[0] is XmlSchemaElement) throw new XmlException("Invalid wsdl:message type: " + ((XmlSchemaElement)messageTypes[0]).Name + ". Rpc/Literal message parts must contain type attributes or no attributes."); // Generate Rpc style contracts GenerateWrappedContracts(BindingStyle.Rpc, operationMessage, messageParts, messageTypes); } }
/// <summary> /// For a given wsdl service operation, generate an Rpc or document style wrapped data contract /// and data contract serializer. /// </summary> /// <param name="BindingStyle">A flag indicating the binding style.</param> /// <param name="operationMessage">A OperationMessage type containing an OperationInput or OperationOutput type.</param> /// <param name="messageParts">A collection of message parts used by the operation.</param> /// <param name="messageTypes">An arraylist of message elements and or types used by the operation.</param> private void GenerateWrappedContracts(BindingStyle bindingStyle, OperationMessage operationMessage, MessagePartCollection messageParts, ArrayList messageTypes) { if (messageTypes.Count == 0) return; // Rules: Rpc/Literal support only. WS-I basic profile Rpc/Literal rules apply. // Create a temporary wrapper element type that will be used to wrap the message parts. // As per rpc/literal spec the name of the type is the name of the operation // If the message is a response the name = the operation name + "Response". // The temporary wrapper element is stored in a new schema that will be added to the existing // ServiceDescription schema set and recompiled to resolve all type references. XmlSchema schema = operationMessage.Operation.PortType.ServiceDescription.Types.Schemas[0]; XmlSchemaSet schemaSet = new XmlSchemaSet(); XmlSchemaElement wrapperElement = new XmlSchemaElement(); schema.Items.Add(wrapperElement); string elementName = operationMessage.Operation.Name; elementName = operationMessage is OperationOutput ? elementName + "Response" : elementName + "Request"; wrapperElement.Name = elementName; // The element namespace is the target namespace by default else it is // defined by the binding/operation/soap12Body/namespace attribute schema.TargetNamespace = CodeGenUtils.GetOperationNamespace(operationMessage); // Add a new complex type to the element XmlSchemaComplexType complexType = new XmlSchemaComplexType(); wrapperElement.SchemaType = complexType; // Add a sequence particles to the complex type XmlSchemaSequence sequence = new XmlSchemaSequence(); complexType.Particle = sequence; // Loop through the list of parts and add thier definitions to the sequence for (int i = 0; i < messageTypes.Count; ++i) { if (bindingStyle == BindingStyle.Rpc) { XmlSchemaElement typeElement = new XmlSchemaElement(); typeElement.Name = messageParts[i].Name; typeElement.SchemaTypeName = new XmlQualifiedName(messageParts[i].Type.Name, messageParts[i].Type.Namespace); sequence.Items.Add(typeElement); schema.Items.Add((XmlSchemaType)messageTypes[i]); } else sequence.Items.Add((XmlSchemaElement)messageTypes[i]); } // Add the new schema containing the new element to a set and compile schemaSet.Add(schema); schemaSet.Compile(); // Build the new element and serializer CodeTypeDeclaration codeType = new CodeTypeDeclaration(); CodeNamespace codeNs = CodeGenUtils.GetDotNetNamespace(m_codeNamespaces, wrapperElement.QualifiedName.Namespace); BuildElementType(wrapperElement, codeType); if (!CodeGenUtils.TypeExists(codeNs, codeType.Name)) { codeNs.Types.Add(codeType); m_dcsCodeGen.BuildDataContractSerializer(m_encodingType, codeType, codeNs); } // Swap the existing message parts with a new replacement part. All subsequent processing // will use the new single message part foreach (Message message in operationMessage.Operation.PortType.ServiceDescription.Messages) { if (message.Name == operationMessage.Message.Name) { MessagePart replacementPart = new MessagePart(); replacementPart.Element = new XmlQualifiedName(elementName); replacementPart.Type = wrapperElement.QualifiedName; replacementPart.Name = operationMessage.Name; replacementPart.Namespaces = operationMessage.Namespaces; message.Parts.Clear(); message.Parts.Add(replacementPart); break; } } }
public Message() { extensions = new ServiceDescriptionFormatExtensionCollection(this); parts = new MessagePartCollection(this); serviceDescription = null; }