1
//-----------------------------------------------------------------------
2 // <copyright file="Request.cs" company="Andrew Arnott">
3 // Copyright (c) Andrew Arnott. All rights reserved.
5 //-----------------------------------------------------------------------
7 namespace DotNetOpenAuth
.OpenId
.Provider
{
9 using System
.Collections
.Generic
;
12 using DotNetOpenAuth
.Messaging
;
13 using DotNetOpenAuth
.OpenId
.Messages
;
15 internal abstract class Request
: IRequest
{
16 private readonly OpenIdProvider provider
;
17 private readonly IDirectedProtocolMessage request
;
18 private readonly IProtocolMessageWithExtensions extensibleMessage
;
19 private List
<IOpenIdMessageExtension
> extensions
= new List
<IOpenIdMessageExtension
>();
20 private UserAgentResponse cachedUserAgentResponse
;
22 protected Request(OpenIdProvider provider
, IDirectedProtocolMessage request
) {
23 ErrorUtilities
.VerifyArgumentNotNull(provider
, "provider");
24 ErrorUtilities
.VerifyArgumentNotNull(request
, "request");
26 this.provider
= provider
;
27 this.request
= request
;
28 this.extensibleMessage
= request
as IProtocolMessageWithExtensions
;
31 #region IRequest Members
33 public abstract bool IsResponseReady { get; }
37 protected OpenIdProvider Provider
{
38 get { return this.provider; }
41 protected IDirectedProtocolMessage RequestMessage
{
42 get { return this.request; }
45 protected abstract IProtocolMessage ResponseMessage { get; }
47 protected Protocol Protocol
{
48 get { return Protocol.Lookup(this.RequestMessage.Version); }
51 #region IRequest Methods
53 public void AddResponseExtension(IOpenIdMessageExtension extension
) {
54 ErrorUtilities
.VerifyArgumentNotNull(extension
, "extension");
56 // Because the derived AuthenticationRequest class can swap out
57 // one response message for another (auth vs. no-auth), and because
58 // some response messages support extensions while others don't,
59 // we just add the extensions to a collection here and add them
60 // to the response on the way out.
61 this.extensions
.Add(extension
);
62 this.ResetUserAgentResponse();
65 public T GetExtension
<T
>() where T
: IOpenIdMessageExtension
, new() {
66 if (this.extensibleMessage
!= null) {
67 return this.extensibleMessage
.Extensions
.OfType
<T
>().SingleOrDefault();
73 public IOpenIdMessageExtension
GetExtension(Type extensionType
) {
74 ErrorUtilities
.VerifyArgumentNotNull(extensionType
, "extensionType");
75 if (this.extensibleMessage
!= null) {
76 return this.extensibleMessage
.Extensions
.OfType
<IOpenIdMessageExtension
>().Where(ext
=> extensionType
.IsInstanceOfType(ext
)).SingleOrDefault();
82 public UserAgentResponse
GetResponse() {
83 if (this.cachedUserAgentResponse
== null && this.IsResponseReady
) {
84 if (this.extensions
.Count
> 0) {
85 var extensibleResponse
= this.ResponseMessage
as IProtocolMessageWithExtensions
;
86 ErrorUtilities
.VerifyOperation(extensibleResponse
!= null, MessagingStrings
.MessageNotExtensible
, this.ResponseMessage
.GetType().Name
);
87 foreach (var extension
in this.extensions
) {
88 // It's possible that a prior call to this property
89 // has already added some/all of the extensions to the message.
90 // We don't have to worry about deleting old ones because
91 // this class provides no facility for removing extensions
92 // that are previously added.
93 if (!extensibleResponse
.Extensions
.Contains(extension
)) {
94 extensibleResponse
.Extensions
.Add(extension
);
99 this.cachedUserAgentResponse
= this.provider
.Channel
.Send(this.ResponseMessage
);
102 return this.cachedUserAgentResponse
;
108 /// Resets any user agent response that may have been created already and cached.
110 protected void ResetUserAgentResponse() {
111 this.cachedUserAgentResponse
= null;