3using System.Collections.Generic;
6using System.Threading.Tasks;
16 private readonly Dictionary<string, UPnPArgument> argumentByName =
new Dictionary<string, UPnPArgument>();
18 private readonly XmlElement xml;
20 private readonly
string name;
24 List<UPnPArgument>
Arguments =
new List<UPnPArgument>();
29 foreach (XmlNode N
in Xml.ChildNodes)
34 this.name = N.InnerText;
38 foreach (XmlNode N2
in N.ChildNodes)
40 if (N2.LocalName ==
"argument")
44 this.argumentByName[Argument.
Name] = Argument;
57 public XmlElement
Xml => this.xml;
62 public string Name => this.name;
80 public object Invoke(out Dictionary<string, object> OutputValues, params KeyValuePair<string, object>[] InputValues)
82 return this.
Invoke(out OutputValues, 10000, InputValues);
91 public object Invoke(Dictionary<string, object> InputValues, out Dictionary<string, object> OutputValues)
93 return this.
Invoke(InputValues, out OutputValues, 10000);
103 public object Invoke(out Dictionary<string, object> OutputValues,
int Timeout, params KeyValuePair<string, object>[] InputValues)
105 Dictionary<string, object> InputValues2 =
new Dictionary<string, object>();
107 foreach (KeyValuePair<string, object> P
in InputValues)
108 InputValues2[P.Key] = P.Value;
110 return this.
Invoke(InputValues2, out OutputValues, Timeout);
120 public object Invoke(Dictionary<string, object> InputValues, out Dictionary<string, object> OutputValues,
int Timeout)
122 KeyValuePair<object, Dictionary<string, object>> Result = this.
InvokeAsync(InputValues, Timeout).Result;
123 OutputValues = Result.Value;
133 public Task<KeyValuePair<object, Dictionary<string, object>>>
InvokeAsync(
int Timeout, params KeyValuePair<string, object>[] InputValues)
135 Dictionary<string, object> InputValues2 =
new Dictionary<string, object>();
137 foreach (KeyValuePair<string, object> P
in InputValues)
138 InputValues2[P.Key] = P.Value;
149 public async Task<KeyValuePair<object, Dictionary<string, object>>>
InvokeAsync(Dictionary<string, object> InputValues,
int Timeout)
151 Dictionary<string, object> OutputValues;
152 StringBuilder Soap =
new StringBuilder();
154 object Result =
null;
157 Soap.AppendLine(
"<?xml version=\"1.0\"?>");
158 Soap.AppendLine(
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">");
159 Soap.AppendLine(
"<s:Body>");
161 Soap.Append(this.name);
162 Soap.Append(
" xmlns:u=\"");
164 Soap.AppendLine(
"\">");
171 Soap.Append(Argument.
Name);
174 if (InputValues.TryGetValue(Argument.
Name, out
object Value) &&
181 Soap.Append(Argument.
Name);
187 Soap.Append(this.name);
188 Soap.AppendLine(
">");
189 Soap.AppendLine(
"</s:Body>");
190 Soap.AppendLine(
"</s:Envelope>");
192 using (HttpClient HttpClient =
new HttpClient())
194 HttpClient.Timeout = TimeSpan.FromMilliseconds(Timeout);
195 HttpClient.DefaultRequestHeaders.ExpectContinue =
false;
197 HttpContent Body =
new StringContent(Soap.ToString(), Encoding.UTF8,
"text/xml");
198 Body.Headers.Add(
"SOAPACTION",
"\"" + this.parent.Service.ServiceType +
"#" +
this.name +
"\"");
200 XmlDocument ResponseXml;
202 HttpResponseMessage Response = await HttpClient.PostAsync(this.parent.Service.ControlURI, Body);
203 Stream Stream = await Response.Content.ReadAsStreamAsync();
205 ResponseXml =
new XmlDocument()
207 PreserveWhitespace =
true
209 ResponseXml.Load(Stream);
211 if (ResponseXml.DocumentElement is
null ||
212 ResponseXml.DocumentElement.LocalName !=
"Envelope" ||
213 ResponseXml.DocumentElement.NamespaceURI !=
"http://schemas.xmlsoap.org/soap/envelope/")
215 throw new Exception(
"Unexpected response returned.");
218 XmlElement ResponseBody = GetChildElement(ResponseXml.DocumentElement,
"Body",
"http://schemas.xmlsoap.org/soap/envelope/")
219 ??
throw new Exception(
"Response body not found.");
221 XmlElement ActionResponse = GetChildElement(ResponseBody, this.name +
"Response", this.parent.Service.ServiceType);
222 if (ActionResponse is
null)
224 XmlElement ResponseFault = GetChildElement(ResponseBody,
"Fault",
"http://schemas.xmlsoap.org/soap/envelope/")
225 ??
throw new Exception(
"Unable to parse response.");
227 string FaultCode =
string.Empty;
228 string FaultString =
string.Empty;
229 string UPnPErrorCode =
string.Empty;
230 string UPnPErrorDescription =
string.Empty;
232 foreach (XmlNode N
in ResponseFault.ChildNodes)
237 FaultCode = N.InnerText;
241 FaultString = N.InnerText;
245 foreach (XmlNode N2
in N.ChildNodes)
247 switch (N2.LocalName)
250 foreach (XmlNode N3
in N2.ChildNodes)
252 switch (N3.LocalName)
255 UPnPErrorCode = N3.InnerText;
258 case "errorDescription":
259 UPnPErrorDescription = N3.InnerText;
270 throw new UPnPException(FaultCode, FaultString, UPnPErrorCode, UPnPErrorDescription);
275 OutputValues =
new Dictionary<string, object>();
277 foreach (XmlNode N
in ActionResponse.ChildNodes)
283 if (this.argumentByName.TryGetValue(E.LocalName, out
UPnPArgument Argument2))
285 if (!((Variable = this.parent.GetVariable(Argument2.RelatedStateVariable)) is
null))
287 object Value2 = Variable.XmlStringToValue(E.InnerText);
288 OutputValues[E.LocalName] = Value2;
293 if (Argument2.ReturnValue && Result is
null)
301 OutputValues[E.LocalName] = E.InnerXml;
309 OutputValues[E.LocalName] = E.InnerXml;
317 return new KeyValuePair<object, Dictionary<string, object>>(Result, OutputValues);
320 private static XmlElement GetChildElement(XmlElement E,
string LocalName,
string Namespace)
324 foreach (XmlNode N
in E.ChildNodes)
326 E2 = N as XmlElement;
330 if (E2.LocalName == LocalName && E2.NamespaceURI == Namespace)
344 if (AttributeValue is
null || AttributeValue.IndexOfAny(reservedCharacters) < 0)
345 return AttributeValue;
347 return AttributeValue.
348 Replace(
"&",
"&").
349 Replace(
"<",
"<").
350 Replace(
">",
">").
351 Replace(
"\"",
""").
352 Replace(
"'",
"'");
355 private static readonly
char[] reservedCharacters =
new char[] {
'&',
'<',
'>',
'"',
'\'' };
Contains the information provided in a Service Description Document, downloaded from a service in the...
Contains information about an action.
object Invoke(out Dictionary< string, object > OutputValues, int Timeout, params KeyValuePair< string, object >[] InputValues)
Invokes the action.
Task< KeyValuePair< object, Dictionary< string, object > > > InvokeAsync(int Timeout, params KeyValuePair< string, object >[] InputValues)
Invokes the action.
object Invoke(Dictionary< string, object > InputValues, out Dictionary< string, object > OutputValues)
Invokes the action.
object Invoke(Dictionary< string, object > InputValues, out Dictionary< string, object > OutputValues, int Timeout)
Invokes the action.
UPnPArgument[] Arguments
Service Arguments.
object Invoke(out Dictionary< string, object > OutputValues, params KeyValuePair< string, object >[] InputValues)
Invokes the action.
XmlElement Xml
Underlying XML definition.
static string XmlAttributeEncode(string AttributeValue)
Encodes an XML attribute.
async Task< KeyValuePair< object, Dictionary< string, object > > > InvokeAsync(Dictionary< string, object > InputValues, int Timeout)
Invokes the action.
Contains information about an argument.
string RelatedStateVariable
Related State Variable
ArgumentDirection Direction
Argument Direction
Contains information about a state variable.
ArgumentDirection
Direction of action arguments.