2 // System.ServiceModel.EndpointAddress.cs
4 // Author: Duncan Mak (duncan@novell.com)
5 // Atsushi Enomoto (atsushi@ximian.com)
7 // Copyright (C) 2005-2006 Novell, Inc (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Reflection;
32 using System.Resources;
33 using System.Runtime.Serialization;
34 using System.Security.Cryptography.X509Certificates;
36 using System.Xml.Schema;
37 using System.Xml.Serialization;
38 using System.ServiceModel.Channels;
39 using System.ServiceModel.Description;
41 using System.Security.Cryptography.Xml;
44 namespace System.ServiceModel
46 public class EndpointAddress
48 static readonly Uri w3c_anonymous = new Uri (Constants.WsaAnonymousUri);
49 static readonly Uri anonymous_role = new Uri ("http://schemas.microsoft.com/2005/12/ServiceModel/Addressing/Anonymous");
50 static readonly Uri none_role = new Uri ("http://schemas.microsoft.com/2005/12/ServiceModel/Addressing/None");
52 public static Uri AnonymousUri {
53 get { return anonymous_role; }
56 public static Uri NoneUri {
57 get { return none_role; }
61 AddressHeaderCollection headers;
62 EndpointIdentity identity;
63 XmlDictionaryReader metadata_reader;
64 XmlDictionaryReader extension_reader;
66 static XmlSchema schema;
68 public EndpointAddress (string uri)
69 : this (new Uri (uri), new AddressHeader [0])
73 public EndpointAddress (Uri uri, params AddressHeader [] addressHeaders)
74 : this (uri, null, new AddressHeaderCollection (addressHeaders), null, null) {}
76 public EndpointAddress (Uri uri, EndpointIdentity identity, params AddressHeader [] addressHeaders)
77 : this (uri, identity, new AddressHeaderCollection (addressHeaders), null, null) {}
79 public EndpointAddress (Uri uri, EndpointIdentity identity, AddressHeaderCollection headers)
80 : this (uri, identity, headers, null, null) {}
82 public EndpointAddress (
83 Uri uri, EndpointIdentity identity,
84 AddressHeaderCollection headers,
85 XmlDictionaryReader metadataReader,
86 XmlDictionaryReader extensionReader)
89 throw new ArgumentNullException ("uri");
90 if (!uri.IsAbsoluteUri)
91 throw new ArgumentException ("The argument uri must be absolute");
93 this.identity = identity;
94 this.headers = headers;
95 metadata_reader = metadataReader;
96 extension_reader = extensionReader;
99 public bool IsAnonymous {
100 get { return address.Equals (anonymous_role); }
104 get { return address.Equals (none_role); }
107 public AddressHeaderCollection Headers {
108 get { return headers; }
111 public EndpointIdentity Identity {
112 get { return identity; }
116 get { return address; }
120 internal static XmlSchema Schema {
122 if (schema == null) {
123 Assembly a = Assembly.GetCallingAssembly ();
124 Stream s = a.GetManifestResourceStream ("WS-Addressing.schema");
125 schema = XmlSchema.Read (s, null);
134 public void ApplyTo (Message message)
136 throw new NotImplementedException ();
139 public override bool Equals (object obj)
141 EndpointAddress other = obj as EndpointAddress;
143 other.Uri == null || !other.Uri.Equals (this.Uri) ||
144 other.Headers.Count != this.Headers.Count)
147 foreach (AddressHeader h in this.Headers) {
149 foreach (AddressHeader o in other.Headers)
161 public override int GetHashCode ()
163 return address.GetHashCode ();
166 public XmlDictionaryReader GetReaderAtExtensions ()
168 return extension_reader;
171 public XmlDictionaryReader GetReaderAtMetadata ()
173 return metadata_reader;
176 public static bool operator == (EndpointAddress address1, EndpointAddress address2)
178 if ((object) address1 == null)
179 return (object) address2 == null;
180 if ((object) address2 == null)
182 return address1.Equals (address2);
185 public static bool operator != (EndpointAddress address1, EndpointAddress address2)
187 return ! (address1 == address2);
191 public static EndpointAddress ReadFrom (
192 XmlDictionaryReader reader)
195 throw new ArgumentNullException ("reader");
197 return ReadFromInternal (null, reader, null, null, null, null);
200 public static EndpointAddress ReadFrom (
201 AddressingVersion addressingVersion,
202 XmlDictionaryReader reader)
204 return ReadFrom (addressingVersion, (XmlReader) reader);
207 public static EndpointAddress ReadFrom (
208 AddressingVersion addressingVersion,
211 if (addressingVersion == null)
212 throw new ArgumentNullException ("addressingVersion");
214 throw new ArgumentNullException ("reader");
216 return ReadFromInternal (addressingVersion, reader, null, null, null, null);
219 public static EndpointAddress ReadFrom (
220 XmlDictionaryReader reader,
221 XmlDictionaryString localName,
222 XmlDictionaryString ns)
224 return ReadFrom (AddressingVersion.WSAddressing10,
225 reader, localName, ns);
228 public static EndpointAddress ReadFrom (
229 AddressingVersion addressingVersion,
230 XmlDictionaryReader reader,
231 XmlDictionaryString localName,
232 XmlDictionaryString ns)
234 // Empty localName and ns will be rejected by ReadStartElement() by feeding empty strings.
235 return ReadFromInternal (addressingVersion, reader, null, null, localName ?? XmlDictionaryString.Empty, ns ?? XmlDictionaryString.Empty);
238 public static EndpointAddress ReadFrom (
239 AddressingVersion addressingVersion,
240 XmlReader reader, string localName, string ns)
242 // Empty localName and ns will be rejected by ReadStartElement() by feeding empty strings.
243 return ReadFromInternal (addressingVersion, reader, localName ?? String.Empty, ns ?? String.Empty, null, null);
246 private static EndpointAddress ReadFromInternal (
247 AddressingVersion addressingVersion,
248 XmlReader reader, string localName, string ns,
249 XmlDictionaryString dictLocalName,
250 XmlDictionaryString dictNS)
252 reader.MoveToContent ();
253 if (reader.NodeType != XmlNodeType.Element ||
254 reader.IsEmptyElement)
255 throw new ArgumentException ("Cannot detect appropriate WS-Addressing Address element.");
257 if (localName != null)
258 reader.ReadStartElement (localName, ns);
259 else if (dictLocalName != null)
260 ((XmlDictionaryReader) reader).ReadStartElement (dictLocalName, dictNS);
262 reader.ReadStartElement ();
263 reader.MoveToContent ();
265 if (addressingVersion == null) {
266 if (reader.NamespaceURI == AddressingVersion.WSAddressing10.Namespace)
267 addressingVersion = AddressingVersion.WSAddressing10;
269 if (reader.NamespaceURI == AddressingVersion.WSAddressingAugust2004.Namespace)
270 addressingVersion = AddressingVersion.WSAddressingAugust2004;
272 throw new ArgumentException ("Cannot detect appropriate WS-Addressing version.");
275 EndpointAddress ea = ReadContents (addressingVersion, reader);
277 reader.MoveToContent ();
278 reader.ReadEndElement ();
282 private static EndpointAddress ReadContents (
283 AddressingVersion addressingVersion, XmlReader reader)
286 EndpointIdentity identity = null;
287 reader.MoveToContent ();
288 if (reader.LocalName == "Address" &&
289 reader.NamespaceURI == addressingVersion.Namespace &&
290 reader.NodeType == XmlNodeType.Element &&
291 !reader.IsEmptyElement)
292 uri = new Uri (reader.ReadElementContentAsString ());
294 throw new XmlException (String.Format (
295 "Expecting 'Address' from namespace '{0}', but found '{1}' from namespace '{2}'",
296 addressingVersion.Namespace, reader.LocalName, reader.NamespaceURI));
298 reader.MoveToContent ();
300 MetadataSet metadata = null;
301 if (reader.LocalName == "Metadata" &&
302 reader.NamespaceURI == addressingVersion.Namespace &&
303 !reader.IsEmptyElement) {
305 metadata = (MetadataSet) new XmlSerializer (typeof (MetadataSet)).Deserialize (reader);
306 reader.MoveToContent ();
307 reader.ReadEndElement ();
309 reader.MoveToContent ();
310 if (reader.LocalName == "Identity" &&
311 reader.NamespaceURI == Constants.WsaIdentityUri) {
317 if (addressingVersion == AddressingVersion.WSAddressing10 && uri == w3c_anonymous)
318 uri = anonymous_role;
321 return new EndpointAddress (uri, identity);
323 if (metadata == null)
324 return new EndpointAddress (uri, identity);
325 return new EndpointAddress (uri, identity,
326 AddressHeader.CreateAddressHeader (metadata));
330 public override string ToString ()
332 return address.ToString ();
335 public void WriteContentsTo (
336 AddressingVersion addressingVersion,
337 XmlDictionaryWriter writer)
340 throw new ArgumentNullException ("writer");
342 if (addressingVersion == AddressingVersion.None) {
343 writer.WriteString (Uri.AbsoluteUri);
345 writer.WriteStartElement ("Address", addressingVersion.Namespace);
346 writer.WriteString (Uri.AbsoluteUri);
347 writer.WriteEndElement ();
350 if (addressingVersion == AddressingVersion.None)
351 writer.WriteString (Uri.AbsoluteUri);
353 writer.WriteStartElement ("Address", addressingVersion.Namespace);
354 writer.WriteString (Uri.AbsoluteUri);
355 writer.WriteEndElement ();
357 if (Identity == null)
361 foreach (AddressHeader ah in Headers)
362 ah.WriteAddressHeader (writer);
364 writer.WriteStartElement ("Identity", Constants.WsaIdentityUri);
366 X509CertificateEndpointIdentity x509 =
367 Identity as X509CertificateEndpointIdentity;
369 KeyInfo ki = new KeyInfo ();
370 KeyInfoX509Data x = new KeyInfoX509Data ();
371 foreach (X509Certificate2 cert in x509.Certificates)
372 x.AddCertificate (cert);
374 ki.GetXml ().WriteTo (writer);
376 DataContractSerializer ds = new DataContractSerializer (Identity.IdentityClaim.GetType ());
377 ds.WriteObject (writer, Identity.IdentityClaim);
379 writer.WriteEndElement ();
384 public void WriteContentsTo (
385 AddressingVersion addressingVersion,
388 WriteContentsTo (addressingVersion,
389 XmlDictionaryWriter.CreateDictionaryWriter (writer));
392 public void WriteTo (
393 AddressingVersion addressingVersion,
394 XmlDictionaryWriter writer)
396 WriteTo (addressingVersion, writer, "EndpointReference", addressingVersion.Namespace);
399 public void WriteTo (
400 AddressingVersion addressingVersion, XmlWriter writer)
402 WriteTo (addressingVersion,
403 XmlDictionaryWriter.CreateDictionaryWriter (writer));
406 public void WriteTo (
407 AddressingVersion addressingVersion,
408 XmlDictionaryWriter writer,
409 XmlDictionaryString localname,
410 XmlDictionaryString ns)
412 writer.WriteStartElement (localname, ns);
413 WriteContentsTo (addressingVersion, writer);
414 writer.WriteEndElement ();
417 public void WriteTo (
418 AddressingVersion addressingVersion,
419 XmlWriter writer, string localname, string ns)
421 writer.WriteStartElement (localname, ns);
422 WriteContentsTo (addressingVersion, writer);
423 writer.WriteEndElement ();