/// <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> /// Default constructor /// </summary> public MMSMessage() { _Subject = null; _ReceiverNumber = null; _SenderNumber = null; _MessageId = -1; _RequestReceipt = false; _Status = MessageStatus.New; _Reference = null; _Network = null; _Tariff = 0; _FailedReason = null; Parts = new MessagePartCollection(); }
/// <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)); } }
public static void Main() { Console.WriteLine(""); Console.WriteLine("MessagePartCollection Sample"); Console.WriteLine("============================"); Console.WriteLine(""); ServiceDescription myServiceDescription = ServiceDescription.Read("MathService.wsdl"); // Get the message collection. MessageCollection myMessageCollection = myServiceDescription.Messages; Console.WriteLine("Total Messages in the document = " + myServiceDescription.Messages.Count); Console.WriteLine(""); Console.WriteLine("Enumerating PartCollection for each message..."); Console.WriteLine(""); // Get the message part collection for each message. for (int i = 0; i < myMessageCollection.Count; ++i) { Console.WriteLine("Message : " + myMessageCollection[i].Name); // Get the message part collection. MessagePartCollection myMessagePartCollection = myMessageCollection[i].Parts; // Display the part collection. for (int k = 0; k < myMessagePartCollection.Count; k++) { Console.WriteLine("\t Part Name : " + myMessagePartCollection[k].Name); Console.WriteLine("\t Message Name : " + myMessagePartCollection[k].Message.Name); } Console.WriteLine(""); } Console.WriteLine("Displaying the array copied from the " + "MessagePartCollection for the message AddHttpGetIn."); Message myLocalMessage = myServiceDescription.Messages["AddHttpPostOut"]; if (myMessageCollection.Contains(myLocalMessage)) { Console.WriteLine("Message : " + myLocalMessage.Name); // Get the message part collection. MessagePartCollection myMessagePartCollection = myLocalMessage.Parts; MessagePart[] myMessagePart = new MessagePart[myMessagePartCollection.Count]; // Copy the MessagePartCollection to an array. myMessagePartCollection.CopyTo(myMessagePart, 0); for (int k = 0; k < myMessagePart.Length; k++) { Console.WriteLine("\t Part Name : " + myMessagePartCollection[k].Name); } Console.WriteLine(""); } Console.WriteLine("Checking if message is AddHttpPostOut..."); Message myMessage = myServiceDescription.Messages["AddHttpPostOut"]; if (myMessageCollection.Contains(myMessage)) { // Get the message part collection. MessagePartCollection myMessagePartCollection = myMessage.Parts; // Get the part named Body. MessagePart myMessagePart = myMessage.Parts["Body"]; if (myMessagePartCollection.Contains(myMessagePart)) { // Get the index of the part named Body. Console.WriteLine("Index of Body in MessagePart collection = " + myMessagePartCollection.IndexOf(myMessagePart)); Console.WriteLine("Deleting Body from MessagePart collection..."); myMessagePartCollection.Remove(myMessagePart); if (myMessagePartCollection.IndexOf(myMessagePart) == -1) { Console.WriteLine("MessagePart Body successfully deleted " + "from the message AddHttpPostOut."); } } } }
/// <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); } } // 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 { 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> /// CreateSourceFiles - Parse Wsdl Schema and generate DataContract, DataContractSerializer types, /// HostedServices and Client Proxies. /// </summary> /// <remarks>Currently only generates C# source files.</remarks> /// <param name="contractFilename">The name of a contract source code (.cs) file.</param> /// <param name="hostedServiceFilename">The name of a hosted service source code (.cs) file.</param> /// <param name="clientProxyFilename">The name of a client proxy source code (.cs) file.</param> /// <param name="targetPlatform">Specifies the target runtime platform.</param> public void CreateSourceFiles(string contractFilename, string hostedServiceFilename, string clientProxyFilename, TargetPlatform targetPlatform) { m_platform = targetPlatform; Logger.WriteLine("", LogLevel.Normal); Logger.WriteLine("Generating contract source: " + contractFilename + "...", LogLevel.Normal); if (contractFilename == null) { throw new ArgumentNullException("codeFilename", "You must pass a valid code filename."); } if (m_svcDesc.Types == null) { throw new Exception("No wsdl types found."); } string path = Path.GetDirectoryName(contractFilename).Trim(); if (!string.IsNullOrEmpty(path) && !Directory.Exists(path)) { Directory.CreateDirectory(path); } // Create code file stream FileStream dcStream = new FileStream(contractFilename, FileMode.Create, FileAccess.Write, FileShare.None); StreamWriter dcStreamWriter = new StreamWriter(dcStream); // Write the auto generated header dcStreamWriter.Write(AutoGenTextHeader.Message); try { // Set up data contract code generator CSharpCodeProvider cSharpCP = new CSharpCodeProvider(); ICodeGenerator codeGen = cSharpCP.CreateGenerator(dcStreamWriter); CodeGeneratorOptions codeGenOptions = new CodeGeneratorOptions(); codeGenOptions.BracingStyle = "C"; // Cobble up a valid .net namespace. Turn any progression that's not a-z or A-Z to a single '.' string targetNamespaceName = CodeGenUtils.GenerateDotNetNamespace(m_svcDesc.TargetNamespace); // For some reason we have to force schemas to compile. Though it was suppose to automatically. Huh! foreach (XmlSchema schema in m_svcDesc.Types.Schemas) { XmlSchemaSet schemaSet = new XmlSchemaSet(); schemaSet.Add(schema); schemaSet.Compile(); } // Create new code namespace CodeNamespace targetNamespace = new CodeNamespace(targetNamespaceName); // Add data contract using directives CodeSnippetCompileUnit compileUnit = new CodeSnippetCompileUnit("using System;"); codeGen.GenerateCodeFromCompileUnit(compileUnit, dcStreamWriter, codeGenOptions); compileUnit.Value = "using System.Xml;"; codeGen.GenerateCodeFromCompileUnit(compileUnit, dcStreamWriter, codeGenOptions); if (m_platform == TargetPlatform.MicroFramework) { compileUnit.Value = "using System.Ext;"; codeGen.GenerateCodeFromCompileUnit(compileUnit, dcStreamWriter, codeGenOptions); compileUnit.Value = "using System.Ext.Xml;"; codeGen.GenerateCodeFromCompileUnit(compileUnit, dcStreamWriter, codeGenOptions); } compileUnit.Value = "using Ws.ServiceModel;"; codeGen.GenerateCodeFromCompileUnit(compileUnit, dcStreamWriter, codeGenOptions); compileUnit.Value = "using Ws.Services.Mtom;"; codeGen.GenerateCodeFromCompileUnit(compileUnit, dcStreamWriter, codeGenOptions); compileUnit.Value = "using Ws.Services.Serialization;"; codeGen.GenerateCodeFromCompileUnit(compileUnit, dcStreamWriter, codeGenOptions); compileUnit.Value = "using XmlElement = Ws.Services.Xml.WsXmlNode;"; codeGen.GenerateCodeFromCompileUnit(compileUnit, dcStreamWriter, codeGenOptions); compileUnit.Value = "using XmlAttribute = Ws.Services.Xml.WsXmlAttribute;"; codeGen.GenerateCodeFromCompileUnit(compileUnit, dcStreamWriter, codeGenOptions); compileUnit.Value = "using XmlConvert = Ws.Services.Serialization.WsXmlConvert;"; codeGen.GenerateCodeFromCompileUnit(compileUnit, dcStreamWriter, codeGenOptions); compileUnit.Value = ""; codeGen.GenerateCodeFromCompileUnit(compileUnit, dcStreamWriter, codeGenOptions); compileUnit.Namespaces.Add(targetNamespace); m_dcCodeGen.CodeNamespaces = compileUnit.Namespaces; Logger.WriteLine("", LogLevel.Normal); // Create HostedServices and ClientProxies collections HostedServices hostedServices = new HostedServices(targetNamespaceName); ClientProxies clientProxies = new ClientProxies(targetNamespaceName); // For each PortType process foreach (PortType portType in m_svcDesc.PortTypes) { // For each operation in the port type: // Get input and output message parts. // If the message part is a simple type: // Build HostedService operation. // Else if the message part is an element: // Find elements in Schema // If element type is native xml type: // Build HostedService operation. // Else if element references a simple or complex type: // If simpleType is base xml type with restrictions: // Build HostedService operation. // Else // Build DataContract and DataContractSerializer. // Build HostedService Operation. // // Create instance of a HostedService to hold the port type details HostedService hostedService = new HostedService(portType.Name, m_svcDesc.TargetNamespace, m_platform); // Create instance of ClientProxyGenerator ClientProxy clientProxy = new ClientProxy(portType.Name, m_platform); // Create service contract interface CodeTypeDeclaration serviceCodeType = new CodeTypeDeclaration("I" + portType.Name); CodeAttributeArgument codeAttr = new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(m_svcDesc.TargetNamespace)); CodeAttributeDeclaration codeAttrDecl = new CodeAttributeDeclaration("ServiceContract", codeAttr); serviceCodeType.CustomAttributes.Add(codeAttrDecl); // Check for Policy assertions. If found add policy assertion attributes. Policy assertion attributes // are required to regenerate policy assertions when converting a service to Wsdl. List <PolicyAssertion> policyAssertions = GetPolicyAssertions(); bool OptimizedMimeEncoded = false; foreach (PolicyAssertion assert in policyAssertions) { serviceCodeType.CustomAttributes.Add(CreatePolicyAssertions(assert.Name, assert.Namespace.ToString(), assert.PolicyID)); // if Optimized Mime assertion id found set a processing flag if (assert.Name == "OptimizedMimeSerialization") { OptimizedMimeEncoded = true; } } // Add type declaration serviceCodeType.TypeAttributes = TypeAttributes.Public; serviceCodeType.IsInterface = true; // Create service contract callback client interface CodeTypeDeclaration serviceCallbackCodeType = new CodeTypeDeclaration("I" + portType.Name + "Callback"); // Add type declaration serviceCallbackCodeType.TypeAttributes = TypeAttributes.Public; serviceCallbackCodeType.IsInterface = true; // If the binding contains a ref to Mtom encoding type set the Mtom flag if (OptimizedMimeEncoded) { m_dcCodeGen.EncodingType = MessageEncodingType.Mtom; hostedService.EncodingType = MessageEncodingType.Mtom; clientProxy.EncodingType = MessageEncodingType.Mtom; } // Step through port operations, get method names and parse elements. for (int pt_index = 0; pt_index < portType.Operations.Count; ++pt_index) { Operation operation = portType.Operations[pt_index]; string operationName = operation.Name; string inputMessageName = null; string outputMessageName = null; MessagePartCollection inputMessageParts = null; MessagePartCollection outputMessageParts = null; string inAction = null; string outAction = null; GetAction(portType, operation, m_svcDesc.TargetNamespace, ref inAction, ref outAction); // Oneway request port type if (operation.Messages.Flow == OperationFlow.OneWay) { OperationInput input = operation.Messages.Input; inputMessageName = input.Message.Name; // Add operation for HostedService code generation hostedService.AddOperation(operation, inAction, outAction); // Add method for ClientProxy code generation clientProxy.AddOperation(operation, inAction, outAction); } // Twoway request/response pattern else if (operation.Messages.Flow == OperationFlow.RequestResponse) { OperationInput input = operation.Messages.Input; inputMessageName = input.Message.Name; OperationOutput output = operation.Messages.Output; outputMessageName = output.Message.Name; // Add operation for HostedService code generation hostedService.AddOperation(operation, inAction, outAction); // Add method for ClientProxy code generation clientProxy.AddOperation(operation, inAction, outAction); } // Event pattern else if (operation.Messages.Flow == OperationFlow.Notification) { OperationOutput output = operation.Messages.Output; outputMessageName = output.Message.Name; // Add operation for HostedService code generation hostedService.AddOperation(operation, inAction, outAction); // Add method for ClientProxy code generation clientProxy.AddOperation(operation, inAction, outAction); } // Find input and output message parts collection in messages collection // and store for later. foreach (Message message in m_svcDesc.Messages) { if (inputMessageName != null) { if (message.Name == inputMessageName) { inputMessageParts = message.Parts; // Add operation for HostedService code generation hostedService.Messages.Add(message); // Add Message to ClientProxy generator for later clientProxy.Messages.Add(message); } } if (outputMessageName != null) { if (message.Name == outputMessageName) { outputMessageParts = message.Parts; // Add operation for HostedService code generation hostedService.Messages.Add(message); // Add Message to ClientProxy generator for later clientProxy.Messages.Add(message); } } } try { // Try to generate Data Contracts and DataContractSerializers GenerateTypeContracts(operation, inputMessageParts, outputMessageParts); // If operation flow is notification (event) add OperationContract to ServiceContractCallback // else add OperationContract to ServiceContract if (operation.Messages.Flow == OperationFlow.Notification) { AddServiceOperationToInterface(operation, outAction, serviceCallbackCodeType); } else { AddServiceOperationToInterface(operation, inAction, serviceCodeType); } } catch (Exception e) { dcStreamWriter.Close(); File.Delete(contractFilename); Logger.WriteLine("Failed to generate service code. " + e.Message, LogLevel.Normal); return; } } // Add serviceCodeType Service Contract interface to namespace // A serviceCodeType is added even if the wsdl only contains notifications. In that case // the contract will be empty but the ServiceContract attribute and CallbackContract argument // will be used to point to the notification or callback contract interace targetNamespace.Types.Add(serviceCodeType); // If service contract callback type contains members add callback contract to namespace // and add CallbackContract reference attribute to serviceCodeType contract. if (serviceCallbackCodeType.Members.Count > 0) { // Add the callback argument to the service description attribute CodeAttributeArgument callbackArg = new CodeAttributeArgument("CallbackContract", new CodeTypeOfExpression(serviceCallbackCodeType.Name) ); serviceCodeType.CustomAttributes[0].Arguments.Add(callbackArg); // Add the callback interface to namespace targetNamespace.Types.Add(serviceCallbackCodeType); } // If the hosted service has opeations add to Hosted Services collection for Code Gen if (hostedService.ServiceOperations.Count > 0) { hostedServices.Add(hostedService); } // If the client Proxy service has opeations add to client proxy collection for Code Gen if (clientProxy.ServiceOperations.Count > 0) { clientProxies.Add(clientProxy); } } // MOD: 12-02-08 Added code to handle multiple type namespaces // Generate contract source file foreach (CodeNamespace codeNamespace in compileUnit.Namespaces) { codeGen.GenerateCodeFromNamespace(codeNamespace, dcStreamWriter, codeGenOptions); } dcStreamWriter.Flush(); dcStreamWriter.Close(); // Generate Hosted Service code Logger.WriteLine("Generating Hosted Service source: " + hostedServiceFilename + "...", LogLevel.Normal); HostedServiceGenerator hsGen = new HostedServiceGenerator(); hsGen.GenerateCode(hostedServiceFilename, hostedServices); // Generate Client proxy code Logger.WriteLine("Generating Client Proxy source: " + clientProxyFilename + "...", LogLevel.Normal); ClientProxyGenerator cpGen = new ClientProxyGenerator(); cpGen.GenerateCode(clientProxyFilename, clientProxies); } catch (Exception e) { dcStreamWriter.Close(); File.Delete(contractFilename); Logger.WriteLine("Failed to generate service code. " + e.Message, LogLevel.Normal); throw new Exception("Failed to generate service code. ", e); } }