} // PostXmlRequest() /// <summary> /// Creates the SOAP (XML) envelope. /// </summary> /// <param name="action">The action.</param> /// <param name="input">The input.</param> /// <param name="serviceType">Type of the service.</param> /// <returns> /// An <see cref="XmlDocument" />. /// </returns> private static XmlDocument CreateSoapEnvelope(UpnpServiceAction action, IReadOnlyList <object> input, string serviceType) { var doc = new XmlDocument(); var env = doc.CreateElement("SOAP-ENV", "Envelope", "http://schemas.xmlsoap.org/soap/envelope/"); doc.AppendChild(env); var body = doc.CreateElement("SOAP-ENV", "Body", "http://schemas.xmlsoap.org/soap/envelope/"); env.AppendChild(body); var xaction = doc.CreateElement("m", action.Name, serviceType); body.AppendChild(xaction); for (var i = 0; i < action.ArgumentsIn.Count; i++) { var xarg = doc.CreateElement(action.ArgumentsIn[i].Name); if (input[i] != null) { xarg.InnerText = input[i].ToString(); xaction.AppendChild(xarg); } // if } // foreach return(doc); } // CreateSoapEnvelope()
} // Invoke() #endregion // PUBLIC METHODS //// --------------------------------------------------------------------- #region PRIVATE METHODS /// <summary> /// Evaluates the result. /// </summary> /// <param name="text">The text.</param> /// <param name="action">The action.</param> /// <returns>An array of objects.</returns> /// <exception cref="XmlException">No valid SOAP envelop!</exception> private static object[] EvaluateResult(string text, UpnpServiceAction action) { var output = new List <object>(); var document = XDocument.Parse(text); var xroot = XmlSupport.GetFirstSubNode(document, "Envelope", false); if (xroot == null) { throw new XmlException("No valid SOAP envelop!"); } // if var xbody = XmlSupport.GetFirstSubNode(xroot, "Body"); var xfault = XmlSupport.GetFirstSubNode(xbody, "Fault", false); if (xfault != null) { return(EvaluateFaultResult(xfault)); } // if var xaction = XmlSupport.GetFirstSubNode(xbody, $"{action.Name}Response"); var resultList = from xresult in xaction.Elements() select xresult; foreach (var xresult in resultList) { output.Add(xresult.Value); } // foreach return(output.ToArray()); } // EvaluateResult()
//// --------------------------------------------------------------------- #region PUBLIC METHODS /// <summary> /// Invokes the specified URL. /// </summary> /// <param name="url">The URL.</param> /// <param name="serviceType">Type of the service.</param> /// <param name="action">The action.</param> /// <param name="input">The input.</param> /// <returns>An <see cref="InvokeActionResult"/> object.</returns> public async Task <InvokeActionResult> Invoke(string url, string serviceType, UpnpServiceAction action, object[] input) { if (action.ArgumentsIn.Count > input.Length) { throw new ArgumentException("Not enough input arguments"); } // if var actionText = $"\"{serviceType}#{action.Name}\""; var soapEnvelopeXml = CreateSoapEnvelope(action, input, serviceType); var soapString = "<?xml version=\"1.0\"?>\r\n" + soapEnvelopeXml.OuterXml; var result = new InvokeActionResult(); var response = await PostXmlRequest(url, soapString, actionText); if (response.Content.Headers.Contains("Content-Type")) { response.Content.Headers.Remove("Content-Type"); } // if var content = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { result.Success = false; Log.Error(response.StatusCode); try { var details = EvaluateResult(content, action); var error = details[2] as UpnpError; if (error != null) { result.ErrorCode = error.ErrorCode; result.ErrorMessage = error.ErrorDescription; } // if } catch { // IGNORE } // catch return(result); } // if Log.Debug(content); result.Success = true; result.Output = EvaluateResult(content, action); return(result); } // Invoke()
} // ParseStateVariable() /// <summary> /// Parses the action. /// </summary> /// <param name="element">The element.</param> /// <returns>A <see cref="UpnpServiceAction"/> object.</returns> private static UpnpServiceAction ParseAction(XContainer element) { var action = new UpnpServiceAction(); action.Name = XmlSupport.GetFirstSubNodeValue(element, "name"); var xargumentList = XmlSupport.GetFirstSubNode(element, "argumentList", false); if (xargumentList != null) { var argumentList = from xargument in xargumentList.Elements() where (xargument.Name.LocalName == "argument") select xargument; foreach (var xargument in argumentList) { var argument = ParseArgument(xargument); action.AddArgument(argument); } // foreach } // if return(action); } // ParseAction()
} // GetVariableInfo() /// <summary> /// Adds the action. /// </summary> /// <param name="action">The action.</param> public void AddAction(UpnpServiceAction action) { this.actions.Add(action); } // AddAction()