/// <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; }