1
//-----------------------------------------------------------------------
2 // <copyright file="StoreRequest.cs" company="Andrew Arnott">
3 // Copyright (c) Andrew Arnott. All rights reserved.
5 //-----------------------------------------------------------------------
7 namespace DotNetOpenAuth
.OpenId
.Extensions
.AttributeExchange
{
9 using System
.Collections
.Generic
;
11 using DotNetOpenAuth
.Messaging
;
12 using DotNetOpenAuth
.OpenId
.Messages
;
15 /// The Attribute Exchange Store message, request leg.
17 public sealed class StoreRequest
: ExtensionBase
, IMessageWithEvents
{
19 /// The factory method that may be used in deserialization of this message.
21 internal static readonly OpenIdExtensionFactory
.CreateDelegate Factory
= (typeUri
, data
, baseMessage
) => {
22 if (typeUri
== Constants
.TypeUri
&& baseMessage
is SignedResponseRequest
) {
24 if (data
.TryGetValue("mode", out mode
) && mode
== Mode
) {
25 return new StoreRequest();
33 /// The value of the 'mode' parameter.
35 [MessagePart("mode", IsRequired
= true)]
36 private const string Mode
= "store_request";
39 /// The list of provided attribute values. This field will never be null.
41 private readonly List
<AttributeValues
> attributesProvided
= new List
<AttributeValues
>();
44 /// Initializes a new instance of the <see cref="StoreRequest"/> class.
47 : base(new Version(1, 0), Constants
.TypeUri
, null) {
51 /// Gets a list of all the attributes that are included in the store request.
53 public IEnumerable
<AttributeValues
> Attributes
{
54 get { return this.attributesProvided; }
58 /// Adds a given attribute with one or more values to the request for storage.
59 /// Applicable to Relying Parties only.
61 /// <param name="attribute">The attribute values.</param>
62 public void AddAttribute(AttributeValues attribute
) {
63 ErrorUtilities
.VerifyArgumentNotNull(attribute
, "attribute");
64 ErrorUtilities
.VerifyArgumentNamed(!this.ContainsAttribute(attribute
.TypeUri
), "attribute", OpenIdStrings
.AttributeAlreadyAdded
, attribute
.TypeUri
);
65 this.attributesProvided
.Add(attribute
);
69 /// Adds a given attribute with one or more values to the request for storage.
70 /// Applicable to Relying Parties only.
72 /// <param name="typeUri">The type URI of the attribute.</param>
73 /// <param name="values">The attribute values.</param>
74 public void AddAttribute(string typeUri
, params string[] values
) {
75 this.AddAttribute(new AttributeValues(typeUri
, values
));
79 /// Gets the value(s) associated with a given attribute that should be stored.
80 /// Applicable to Providers only.
82 /// <param name="attributeTypeUri">The type URI of the attribute whose values are being sought.</param>
83 /// <returns>The attribute values.</returns>
84 public AttributeValues
GetAttribute(string attributeTypeUri
) {
85 return this.attributesProvided
.SingleOrDefault(attribute
=> string.Equals(attribute
.TypeUri
, attributeTypeUri
, StringComparison
.Ordinal
));
88 #region IMessageWithEvents Members
91 /// Called when the message is about to be transmitted,
92 /// before it passes through the channel binding elements.
94 void IMessageWithEvents
.OnSending() {
95 var fields
= ((IMessage
)this).ExtraData
;
98 AXUtilities
.SerializeAttributes(fields
, this.attributesProvided
);
102 /// Called when the message has been received,
103 /// after it passes through the channel binding elements.
105 void IMessageWithEvents
.OnReceiving() {
106 var fields
= ((IMessage
)this).ExtraData
;
107 foreach (var att
in AXUtilities
.DeserializeAttributes(fields
)) {
108 this.AddAttribute(att
);
115 /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
117 /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
119 /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
121 /// <exception cref="T:System.NullReferenceException">
122 /// The <paramref name="obj"/> parameter is null.
124 public override bool Equals(object obj
) {
125 var other
= obj
as StoreRequest
;
130 if (this.Version
!= other
.Version
) {
134 if (!MessagingUtilities
.AreEquivalentUnordered(this.Attributes
.ToList(), other
.Attributes
.ToList())) {
142 /// Serves as a hash function for a particular type.
145 /// A hash code for the current <see cref="T:System.Object"/>.
147 public override int GetHashCode() {
149 int hashCode
= this.Version
.GetHashCode();
150 foreach (AttributeValues att
in this.Attributes
) {
151 hashCode
+= att
.GetHashCode();
158 /// Determines whether some attribute has values in this store request.
160 /// <param name="typeUri">The type URI of the attribute in question.</param>
162 /// <c>true</c> if the specified attribute appears in the store request; otherwise, <c>false</c>.
164 private bool ContainsAttribute(string typeUri
) {
165 return this.GetAttribute(typeUri
) != null;