/// <summary> /// Get all wsdl:messages and apply them to predefined operations /// </summary> /// <param name="info"> The WSDLInformation that we modifying </param> /// <returns></returns> public WSDLInformation GetMessages(WSDLInformation info) { // Grab all the messages that are related to Soap List <XmlNode> soapMessages = _messageNodes.Cast <XmlNode>() .Where(n => n.GetTextAttribute("name", "wsdl:message").Contains("Soap")) .ToList(); // Loop through all the messages we get back. foreach (XmlNode message in soapMessages) { // Grab the name of the message and find the type (whether its an input or output type message). string name = message.GetTextAttribute("name", "wsdl:message"); string type = info.GetParameterTypeByName(name); // Find the operation that we are dealing with WSDLOperation operation = info.FindOperationByParameter(name); // Grab the first part we are assuming we only have one part. XmlNode partNode = message.FirstChild; // Determine if its an input or output message and store accordingly. if (type == WSDLHelpers.IN_PARAMETER) { operation.InputMessage = partNode.GetTextAttribute("element", "wsdl:part"); } else if (type == WSDLHelpers.OUT_PARAMETER) { operation.OutputMessage = partNode.GetTextAttribute("element", "wsdl:part"); } } return(info); }
/// <summary> /// Merges the WSDL with the configuration library already present. /// </summary> /// <param name="info">The information.</param> private void MergeWithWSDL(WSDLInformation info) { foreach (WSDLOperation operation in info.Operations) { Method method = GetMethod(info.Port.Location, operation.Name); if (method == null) { continue; } method.Response = operation.OutputTypeInformation.Types.Cast <WSDLType>().First(); method.Namespace = info.Namespace; method.Documentation = operation.Documentation; Parameter[] parameters = method.Parameters; /* Process parameters only if this method has them */ if (parameters != null) { foreach (Parameter parameter in parameters) { WSDLType parameterTypeInfo = operation.InputTypeInformation.Types.Cast <WSDLType>().FirstOrDefault(type => type.Name == parameter.Name); if (parameterTypeInfo != null) { parameter.Type = parameterTypeInfo.Type; } } } SetMethod(method, info.Port.Location, operation.Name); } }
/// <summary> /// Loads the a WSDL for the selected web service, and modifies the /// webservices method and parameter objects to add in additional information /// about the service (parameter types and method namespace). If a WSDL fails to /// load, the service is removed from the library. /// </summary> /// <param name="service">The service to load the WSDL for.</param> /// <returns>Bool if load successful, false otherwise.</returns> private async Task <bool> LoadWSDLAsync(WebService service) { bool loadSuccess = false; try { // Genereate xml document XmlDocument wsdlXml = await SOAPWebService.GetWSDLAsync(service.Url); // Apply WSDL information to our library of configured methods WSDLParser wsdlParser = new WSDLParser(wsdlXml); WSDLInformation wsdlInfo = wsdlParser.BuildWSDLInformation(); MergeWithWSDL(wsdlInfo); loadSuccess = true; } catch (Exception ex) when(ex is WSDLNodeNotFoundException || ex is HttpRequestException || ex is XmlException) { Logger.Log(ex); List <WebService> serviceList = _services.ToList(); serviceList.Remove(service); _services = serviceList.ToArray(); } return(loadSuccess); }
/// <summary> /// Gets the namespace from the WSDL XmlStructure. /// </summary> /// <param name="info">The information.</param> /// <returns></returns> public WSDLInformation GetNamespace(WSDLInformation info) { XmlNode schema = _schemaNodes.Cast <XmlNode>().FirstOrDefault(); info.Namespace = schema.GetTextAttribute("targetNamespace", "wsdl:schema"); return(info); }
/// <summary> /// Goes the WSDL operations xml structure and returns WSDLOperations /// </summary> /// <param name="info">The WSDLInformation we are filing out</param> /// <returns>The filed out WSDLinformation</returns> public WSDLInformation GetOperations(WSDLInformation info) { // Grab the proper binding string binding = info.Port.Binding; XmlNode bindingNode = _bindingNodes.Cast <XmlNode>().First(e => e.GetTextAttribute("name", "wsdl:binding") == binding); // Go through each operation and create an object out of the name and the soapAction info.Operations = bindingNode.ChildNodes.Cast <XmlNode>() .Where(e => e.Name == "wsdl:operation") .Select(e => new WSDLOperation(e.GetTextAttribute("name", "wsdl:operation"), e.FirstChild.GetTextAttribute("soapAction", "wsdl:part"))) .ToList(); return(info); }
/// <summary> /// Helper convience method that parses the XML document in the correct order. /// </summary> /// <returns>A WSDLInformation object based on the wsdl parsed</returns> public WSDLInformation BuildWSDLInformation() { WSDLInformation wsdlInformation = new WSDLInformation(); // Generate the WSDLInformation from the parser. wsdlInformation = GetNamespace(wsdlInformation); wsdlInformation = GetPort(wsdlInformation); wsdlInformation = GetOperations(wsdlInformation); wsdlInformation = GetPortTypes(wsdlInformation); wsdlInformation = GetMessages(wsdlInformation); // Build and apply the type information. List <WSDLTypeInformation> typeInfo = BuildTypeInformation(); wsdlInformation.ApplyTypeInformation(typeInfo); return(wsdlInformation); }
/// <summary> /// Retrieves and parses the portTypes XML structure from the WSDL /// </summary> /// <param name="info">The info to fill out</param> /// <returns></returns> public WSDLInformation GetPortTypes(WSDLInformation info) { // Grab the proper portType string portTypeKey = info.BaseName += WSDLHelpers.SOAP_SUFFIX; XmlNode portTypeNode = _portTypeNodes.Cast <XmlNode>() .First(portType => portType.GetTextAttribute("name", "wsdl:portType") == portTypeKey); // Grab all operations List <XmlNode> operations = portTypeNode.ChildNodes.Cast <XmlNode>().ToList(); foreach (XmlNode o in operations) { // Get the operation that we want. string operationName = o.GetTextAttribute("name", "wsdl:operation"); WSDLOperation operation = info.FindOperationByName(operationName); // Fill out all of the info that we need. Input, Output, Documentation // Grab the documentation tag, it is optiona. XmlNode documentationNode = o.ChildNodes.Cast <XmlNode>().FirstOrDefault(e => e.Name == "wsdl:documentation"); if (documentationNode != null) { operation.Documentation = documentationNode.InnerText; } else { operation.Documentation = "No documentation available at this time"; } // Get the input node and fill it out with whatever is in the tag. XmlNode inputNode = o.ChildNodes.Cast <XmlNode>().First(e => e.Name == "wsdl:input"); operation.Input = inputNode.GetTextAttribute("message", "wsdl:input"); // Get the output node and fill it out with whatever is in the tag. XmlNode outputNode = o.ChildNodes.Cast <XmlNode>().First(e => e.Name == "wsdl:output"); operation.Output = outputNode.GetTextAttribute("message", "wsdl:input"); } return(info); }
/// <summary> /// Retrieves and parses the Port from the WSDL Xml structure /// </summary> /// <param name="info">The WSDL Information we are parsing out </param> /// <returns></returns> public WSDLInformation GetPort(WSDLInformation info) { WSDLPort port = new WSDLPort(); // Grab the wsdl:service to be able to get the name of the service. XmlNode first = _portNodes.Cast <XmlNode>().First().ParentNode; info.Service.Name = first.GetTextAttribute("name", "wsdl:service"); info.BaseName = info.Service.Name; // Generate the portkey to be able to get the direct port that we need. We are focusing on soap12 string portKey = info.Service.Name += WSDLHelpers.SOAP_12_SUFFIX; XmlNode portNode = _portNodes.Cast <XmlNode>().First(p => p.GetTextAttribute("name", "wsdl:portNode") == portKey); // Build the port from the portNode XMLNode. info.Port.Name = WSDLHelpers.TrimNamespace(portNode.GetTextAttribute("name", "wsdl:portNode")); info.Port.Binding = WSDLHelpers.TrimNamespace(portNode.GetTextAttribute("binding", "wsdl:portNode")); info.Port.Location = portNode.FirstChild.GetTextAttribute("location", "soap:address"); return(info); }