diff options
9 files changed, 351 insertions, 47 deletions
diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj index f21e4dc..84dfb97 100644 --- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj +++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj @@ -137,7 +137,7 @@ <Compile Include="Messaging\EnumerableCacheTests.cs" /> <Compile Include="Messaging\ErrorUtilitiesTests.cs" /> <Compile Include="Messaging\MessageSerializerTests.cs" /> - <Compile Include="Messaging\MultiPartPostPartTests.cs" /> + <Compile Include="Messaging\MultipartPostPartTests.cs" /> <Compile Include="Messaging\Reflection\MessageDescriptionTests.cs" /> <Compile Include="Messaging\Reflection\MessageDictionaryTests.cs" /> <Compile Include="Messaging\MessagingTestBase.cs" /> diff --git a/src/DotNetOpenAuth.Test/Messaging/MultiPartPostPartTests.cs b/src/DotNetOpenAuth.Test/Messaging/MultiPartPostPartTests.cs index 95404a4..f87ae59 100644 --- a/src/DotNetOpenAuth.Test/Messaging/MultiPartPostPartTests.cs +++ b/src/DotNetOpenAuth.Test/Messaging/MultiPartPostPartTests.cs @@ -1,5 +1,5 @@ //----------------------------------------------------------------------- -// <copyright file="MultiPartPostPartTests.cs" company="Andrew Arnott"> +// <copyright file="MultipartPostPartTests.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- @@ -14,13 +14,13 @@ namespace DotNetOpenAuth.Test.Messaging { using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] - public class MultiPartPostPartTests : TestBase { + public class MultipartPostPartTests : TestBase { /// <summary> /// Verifies that the Length property matches the length actually serialized. /// </summary> [TestMethod] public void FormDataSerializeMatchesLength() { - var part = MultiPartPostPart.CreateFormPart("a", "b"); + var part = MultipartPostPart.CreateFormPart("a", "b"); VerifyLength(part); } @@ -32,7 +32,7 @@ namespace DotNetOpenAuth.Test.Messaging { using (TempFileCollection tfc = new TempFileCollection()) { string file = tfc.AddExtension(".txt"); File.WriteAllText(file, "sometext"); - var part = MultiPartPostPart.CreateFormFilePart("someformname", file, "text/plain"); + var part = MultipartPostPart.CreateFormFilePart("someformname", file, "text/plain"); VerifyLength(part); } } @@ -45,9 +45,9 @@ namespace DotNetOpenAuth.Test.Messaging { using (TempFileCollection tfc = new TempFileCollection()) { string file = tfc.AddExtension("txt"); File.WriteAllText(file, "sometext"); - this.VerifyFullPost(new List<MultiPartPostPart> { - MultiPartPostPart.CreateFormPart("a", "b"), - MultiPartPostPart.CreateFormFilePart("SomeFormField", file, "text/plain"), + this.VerifyFullPost(new List<MultipartPostPart> { + MultipartPostPart.CreateFormPart("a", "b"), + MultipartPostPart.CreateFormFilePart("SomeFormField", file, "text/plain"), }); } } @@ -60,14 +60,14 @@ namespace DotNetOpenAuth.Test.Messaging { using (TempFileCollection tfc = new TempFileCollection()) { string file = tfc.AddExtension("txt"); File.WriteAllText(file, "\x1020\x818"); - this.VerifyFullPost(new List<MultiPartPostPart> { - MultiPartPostPart.CreateFormPart("a", "\x987"), - MultiPartPostPart.CreateFormFilePart("SomeFormField", file, "text/plain"), + this.VerifyFullPost(new List<MultipartPostPart> { + MultipartPostPart.CreateFormPart("a", "\x987"), + MultipartPostPart.CreateFormFilePart("SomeFormField", file, "text/plain"), }); } } - private static void VerifyLength(MultiPartPostPart part) { + private static void VerifyLength(MultipartPostPart part) { Contract.Requires(part != null); var expectedLength = part.Length; @@ -79,7 +79,7 @@ namespace DotNetOpenAuth.Test.Messaging { Assert.AreEqual(expectedLength, actualLength); } - private void VerifyFullPost(List<MultiPartPostPart> parts) { + private void VerifyFullPost(List<MultipartPostPart> parts) { var request = (HttpWebRequest)WebRequest.Create("http://localhost"); var handler = new Mocks.TestWebRequestHandler(); bool posted = false; diff --git a/src/DotNetOpenAuth.Test/Messaging/MultipartPostPartTests.cs b/src/DotNetOpenAuth.Test/Messaging/MultipartPostPartTests.cs new file mode 100644 index 0000000..f87ae59 --- /dev/null +++ b/src/DotNetOpenAuth.Test/Messaging/MultipartPostPartTests.cs @@ -0,0 +1,99 @@ +//----------------------------------------------------------------------- +// <copyright file="MultipartPostPartTests.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Test.Messaging { + using System.CodeDom.Compiler; + using System.Collections.Generic; + using System.Diagnostics.Contracts; + using System.IO; + using System.Net; + using DotNetOpenAuth.Messaging; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MultipartPostPartTests : TestBase { + /// <summary> + /// Verifies that the Length property matches the length actually serialized. + /// </summary> + [TestMethod] + public void FormDataSerializeMatchesLength() { + var part = MultipartPostPart.CreateFormPart("a", "b"); + VerifyLength(part); + } + + /// <summary> + /// Verifies that the length property matches the length actually serialized. + /// </summary> + [TestMethod] + public void FileSerializeMatchesLength() { + using (TempFileCollection tfc = new TempFileCollection()) { + string file = tfc.AddExtension(".txt"); + File.WriteAllText(file, "sometext"); + var part = MultipartPostPart.CreateFormFilePart("someformname", file, "text/plain"); + VerifyLength(part); + } + } + + /// <summary> + /// Verifies MultiPartPost sends the right number of bytes. + /// </summary> + [TestMethod] + public void MultiPartPostAscii() { + using (TempFileCollection tfc = new TempFileCollection()) { + string file = tfc.AddExtension("txt"); + File.WriteAllText(file, "sometext"); + this.VerifyFullPost(new List<MultipartPostPart> { + MultipartPostPart.CreateFormPart("a", "b"), + MultipartPostPart.CreateFormFilePart("SomeFormField", file, "text/plain"), + }); + } + } + + /// <summary> + /// Verifies MultiPartPost sends the right number of bytes. + /// </summary> + [TestMethod] + public void MultiPartPostMultiByteCharacters() { + using (TempFileCollection tfc = new TempFileCollection()) { + string file = tfc.AddExtension("txt"); + File.WriteAllText(file, "\x1020\x818"); + this.VerifyFullPost(new List<MultipartPostPart> { + MultipartPostPart.CreateFormPart("a", "\x987"), + MultipartPostPart.CreateFormFilePart("SomeFormField", file, "text/plain"), + }); + } + } + + private static void VerifyLength(MultipartPostPart part) { + Contract.Requires(part != null); + + var expectedLength = part.Length; + var ms = new MemoryStream(); + var sw = new StreamWriter(ms); + part.Serialize(sw); + sw.Flush(); + var actualLength = ms.Length; + Assert.AreEqual(expectedLength, actualLength); + } + + private void VerifyFullPost(List<MultipartPostPart> parts) { + var request = (HttpWebRequest)WebRequest.Create("http://localhost"); + var handler = new Mocks.TestWebRequestHandler(); + bool posted = false; + handler.Callback = req => { + foreach (string header in req.Headers) { + TestContext.WriteLine("{0}: {1}", header, req.Headers[header]); + } + TestContext.WriteLine(handler.RequestEntityAsString); + Assert.AreEqual(req.ContentLength, handler.RequestEntityStream.Length); + posted = true; + return null; + }; + request.PostMultipart(handler, parts); + Assert.IsTrue(posted, "HTTP POST never sent."); + } + } +} diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index 3c42217..341b722 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -252,7 +252,7 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="Messaging\IProtocolMessageWithExtensions.cs" /> <Compile Include="Messaging\InternalErrorException.cs" /> <Compile Include="Messaging\KeyedCollectionDelegate.cs" /> - <Compile Include="Messaging\MultiPartPostPart.cs" /> + <Compile Include="Messaging\MultipartPostPart.cs" /> <Compile Include="Messaging\NetworkDirectWebResponse.cs" /> <Compile Include="Messaging\OutgoingWebResponseActionResult.cs" /> <Compile Include="Messaging\Reflection\IMessagePartEncoder.cs" /> diff --git a/src/DotNetOpenAuth/GlobalSuppressions.cs b/src/DotNetOpenAuth/GlobalSuppressions.cs index d0e0d05..313eaeb 100644 --- a/src/DotNetOpenAuth/GlobalSuppressions.cs +++ b/src/DotNetOpenAuth/GlobalSuppressions.cs @@ -48,3 +48,4 @@ [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "icam", Scope = "resource", Target = "DotNetOpenAuth.OpenId.Behaviors.BehaviorStrings.resources")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "idmanagement", Scope = "resource", Target = "DotNetOpenAuth.OpenId.Behaviors.BehaviorStrings.resources")] [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "no-pii", Scope = "resource", Target = "DotNetOpenAuth.OpenId.Behaviors.BehaviorStrings.resources")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "runat", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs index 62a4f64..93c0b6b 100644 --- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs +++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs @@ -148,7 +148,7 @@ namespace DotNetOpenAuth.Messaging { /// <param name="requestHandler">The request handler.</param> /// <param name="parts">The parts to include in the POST entity.</param> /// <returns>The HTTP response.</returns> - public static IncomingWebResponse PostMultipart(this HttpWebRequest request, IDirectWebRequestHandler requestHandler, IEnumerable<MultiPartPostPart> parts) { + public static IncomingWebResponse PostMultipart(this HttpWebRequest request, IDirectWebRequestHandler requestHandler, IEnumerable<MultipartPostPart> parts) { ErrorUtilities.VerifyArgumentNotNull(request, "request"); ErrorUtilities.VerifyArgumentNotNull(requestHandler, "requestHandler"); ErrorUtilities.VerifyArgumentNotNull(parts, "parts"); @@ -644,7 +644,7 @@ namespace DotNetOpenAuth.Messaging { /// Gets the <see cref="HttpDeliveryMethods"/> enum value for a given HTTP verb. /// </summary> /// <param name="httpVerb">The HTTP verb.</param> - /// <returns>A <see cref="HttpDeliveryMethod"/> enum value that is within the <see cref="HttpDeliveryMethods.HttpVerbMask"/>.</returns> + /// <returns>A <see cref="HttpDeliveryMethods"/> enum value that is within the <see cref="HttpDeliveryMethods.HttpVerbMask"/>.</returns> internal static HttpDeliveryMethods GetHttpDeliveryMethod(string httpVerb) { if (httpVerb == "GET") { return HttpDeliveryMethods.GetRequest; diff --git a/src/DotNetOpenAuth/Messaging/MultiPartPostPart.cs b/src/DotNetOpenAuth/Messaging/MultiPartPostPart.cs index 5cdda48..7ef89a4 100644 --- a/src/DotNetOpenAuth/Messaging/MultiPartPostPart.cs +++ b/src/DotNetOpenAuth/Messaging/MultiPartPostPart.cs @@ -1,5 +1,5 @@ //----------------------------------------------------------------------- -// <copyright file="MultiPartPostPart.cs" company="Andrew Arnott"> +// <copyright file="MultipartPostPart.cs" company="Andrew Arnott"> // Copyright (c) Andrew Arnott. All rights reserved. // </copyright> //----------------------------------------------------------------------- @@ -16,7 +16,7 @@ namespace DotNetOpenAuth.Messaging { /// <summary> /// Represents a single part in a HTTP multipart POST request. /// </summary> - public class MultiPartPostPart : IDisposable { + public class MultipartPostPart : IDisposable { /// <summary> /// The "Content-Disposition" string. /// </summary> @@ -28,10 +28,10 @@ namespace DotNetOpenAuth.Messaging { private const string NewLine = "\r\n"; /// <summary> - /// Initializes a new instance of the <see cref="MultiPartPostPart"/> class. + /// Initializes a new instance of the <see cref="MultipartPostPart"/> class. /// </summary> /// <param name="contentDisposition">The content disposition of the part.</param> - public MultiPartPostPart(string contentDisposition) { + public MultipartPostPart(string contentDisposition) { Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(contentDisposition)); this.ContentDisposition = contentDisposition; @@ -98,11 +98,11 @@ namespace DotNetOpenAuth.Messaging { /// <param name="name">The name of the form field.</param> /// <param name="value">The value.</param> /// <returns>The constructed part.</returns> - public static MultiPartPostPart CreateFormPart(string name, string value) { + public static MultipartPostPart CreateFormPart(string name, string value) { Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(name)); Contract.Requires<ArgumentException>(value != null); - var part = new MultiPartPostPart("form-data"); + var part = new MultipartPostPart("form-data"); part.ContentAttributes["name"] = name; part.Content = new MemoryStream(Encoding.UTF8.GetBytes(value)); return part; @@ -115,7 +115,7 @@ namespace DotNetOpenAuth.Messaging { /// <param name="filePath">The path to the file to send.</param> /// <param name="contentType">Type of the content in HTTP Content-Type format.</param> /// <returns>The constructed part.</returns> - public static MultiPartPostPart CreateFormFilePart(string name, string filePath, string contentType) { + public static MultipartPostPart CreateFormFilePart(string name, string filePath, string contentType) { string fileName = Path.GetFileName(filePath); return CreateFormFilePart(name, fileName, contentType, File.OpenRead(filePath)); } @@ -128,13 +128,13 @@ namespace DotNetOpenAuth.Messaging { /// <param name="contentType">Type of the content in HTTP Content-Type format.</param> /// <param name="content">The content of the file.</param> /// <returns>The constructed part.</returns> - public static MultiPartPostPart CreateFormFilePart(string name, string fileName, string contentType, Stream content) { + public static MultipartPostPart CreateFormFilePart(string name, string fileName, string contentType, Stream content) { Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(name)); Contract.Requires<ArgumentException>(fileName != null); Contract.Requires<ArgumentException>(contentType != null); Contract.Requires<ArgumentException>(content != null); - var part = new MultiPartPostPart("form-data"); + var part = new MultipartPostPart("form-data"); part.ContentAttributes["name"] = name; part.ContentAttributes["filename"] = fileName; part.PartHeaders[HttpRequestHeader.ContentType] = contentType; diff --git a/src/DotNetOpenAuth/Messaging/MultipartPostPart.cs b/src/DotNetOpenAuth/Messaging/MultipartPostPart.cs new file mode 100644 index 0000000..7ef89a4 --- /dev/null +++ b/src/DotNetOpenAuth/Messaging/MultipartPostPart.cs @@ -0,0 +1,202 @@ +//----------------------------------------------------------------------- +// <copyright file="MultipartPostPart.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Messaging { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; + using System.IO; + using System.Net; + using System.Text; + + /// <summary> + /// Represents a single part in a HTTP multipart POST request. + /// </summary> + public class MultipartPostPart : IDisposable { + /// <summary> + /// The "Content-Disposition" string. + /// </summary> + private const string ContentDispositionHeader = "Content-Disposition"; + + /// <summary> + /// The two-character \r\n newline character sequence to use. + /// </summary> + private const string NewLine = "\r\n"; + + /// <summary> + /// Initializes a new instance of the <see cref="MultipartPostPart"/> class. + /// </summary> + /// <param name="contentDisposition">The content disposition of the part.</param> + public MultipartPostPart(string contentDisposition) { + Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(contentDisposition)); + + this.ContentDisposition = contentDisposition; + this.ContentAttributes = new Dictionary<string, string>(); + this.PartHeaders = new WebHeaderCollection(); + } + + /// <summary> + /// Gets the content disposition. + /// </summary> + /// <value>The content disposition.</value> + public string ContentDisposition { get; private set; } + + /// <summary> + /// Gets the key=value attributes that appear on the same line as the Content-Disposition. + /// </summary> + /// <value>The content attributes.</value> + public IDictionary<string, string> ContentAttributes { get; private set; } + + /// <summary> + /// Gets the headers that appear on subsequent lines after the Content-Disposition. + /// </summary> + public WebHeaderCollection PartHeaders { get; private set; } + + /// <summary> + /// Gets or sets the content of the part. + /// </summary> + public Stream Content { get; set; } + + /// <summary> + /// Gets the length of this entire part. + /// </summary> + /// <remarks>Useful for calculating the ContentLength HTTP header to send before actually serializing the content.</remarks> + public long Length { + get { + ErrorUtilities.VerifyOperation(this.Content != null && this.Content.Length >= 0, MessagingStrings.StreamMustHaveKnownLength); + + long length = 0; + length += ContentDispositionHeader.Length; + length += ": ".Length; + length += this.ContentDisposition.Length; + foreach (var pair in this.ContentAttributes) { + length += "; ".Length + pair.Key.Length + "=\"".Length + pair.Value.Length + "\"".Length; + } + + length += NewLine.Length; + foreach (string headerName in this.PartHeaders) { + length += headerName.Length; + length += ": ".Length; + length += this.PartHeaders[headerName].Length; + length += NewLine.Length; + } + + length += NewLine.Length; + length += this.Content.Length; + + return length; + } + } + + /// <summary> + /// Creates a part that represents a simple form field. + /// </summary> + /// <param name="name">The name of the form field.</param> + /// <param name="value">The value.</param> + /// <returns>The constructed part.</returns> + public static MultipartPostPart CreateFormPart(string name, string value) { + Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(name)); + Contract.Requires<ArgumentException>(value != null); + + var part = new MultipartPostPart("form-data"); + part.ContentAttributes["name"] = name; + part.Content = new MemoryStream(Encoding.UTF8.GetBytes(value)); + return part; + } + + /// <summary> + /// Creates a part that represents a file attachment. + /// </summary> + /// <param name="name">The name of the form field.</param> + /// <param name="filePath">The path to the file to send.</param> + /// <param name="contentType">Type of the content in HTTP Content-Type format.</param> + /// <returns>The constructed part.</returns> + public static MultipartPostPart CreateFormFilePart(string name, string filePath, string contentType) { + string fileName = Path.GetFileName(filePath); + return CreateFormFilePart(name, fileName, contentType, File.OpenRead(filePath)); + } + + /// <summary> + /// Creates a part that represents a file attachment. + /// </summary> + /// <param name="name">The name of the form field.</param> + /// <param name="fileName">Name of the file as the server should see it.</param> + /// <param name="contentType">Type of the content in HTTP Content-Type format.</param> + /// <param name="content">The content of the file.</param> + /// <returns>The constructed part.</returns> + public static MultipartPostPart CreateFormFilePart(string name, string fileName, string contentType, Stream content) { + Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(name)); + Contract.Requires<ArgumentException>(fileName != null); + Contract.Requires<ArgumentException>(contentType != null); + Contract.Requires<ArgumentException>(content != null); + + var part = new MultipartPostPart("form-data"); + part.ContentAttributes["name"] = name; + part.ContentAttributes["filename"] = fileName; + part.PartHeaders[HttpRequestHeader.ContentType] = contentType; + if (!contentType.StartsWith("text/", StringComparison.Ordinal)) { + part.PartHeaders["Content-Transfer-Encoding"] = "binary"; + } + part.Content = content; + return part; + } + + /// <summary> + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// </summary> + public void Dispose() { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + /// <summary> + /// Serializes the part to a stream. + /// </summary> + /// <param name="streamWriter">The stream writer.</param> + internal void Serialize(StreamWriter streamWriter) { + // VERY IMPORTANT: any changes at all made to this must be kept in sync with the + // Length property which calculates exactly how many bytes this method will write. + streamWriter.NewLine = NewLine; + streamWriter.Write("{0}: {1}", ContentDispositionHeader, this.ContentDisposition); + foreach (var pair in this.ContentAttributes) { + streamWriter.Write("; {0}=\"{1}\"", pair.Key, pair.Value); + } + + streamWriter.WriteLine(); + foreach (string headerName in this.PartHeaders) { + streamWriter.WriteLine("{0}: {1}", headerName, this.PartHeaders[headerName]); + } + + streamWriter.WriteLine(); + streamWriter.Flush(); + this.Content.CopyTo(streamWriter.BaseStream); + } + + /// <summary> + /// Releases unmanaged and - optionally - managed resources + /// </summary> + /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> + protected virtual void Dispose(bool disposing) { + if (disposing) { + this.Content.Dispose(); + } + } + +#if CONTRACTS_FULL + /// <summary> + /// Verifies conditions that should be true for any valid state of this object. + /// </summary> + [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Called by code contracts.")] + [ContractInvariantMethod] + private void Invariant() { + Contract.Invariant(!string.IsNullOrEmpty(this.ContentDisposition)); + Contract.Invariant(this.PartHeaders != null); + Contract.Invariant(this.ContentAttributes != null); + } +#endif + } +} diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.cs index ef65c72..5cf630a 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.cs @@ -67,9 +67,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { #region Property viewstate keys /// <summary> - /// The viewstate key to use for storing the value of the <see cref="AutoPostback"/> property. + /// The viewstate key to use for storing the value of the <see cref="AutoPostBack"/> property. /// </summary> - private const string AutoPostbackViewStateKey = "AutoPostback"; + private const string AutoPostBackViewStateKey = "AutoPostback"; /// <summary> /// The viewstate key to use for the <see cref="Text"/> property. @@ -167,18 +167,18 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { private const string RetryTextViewStateKey = "RetryText"; /// <summary> - /// The viewstate key to use for storing the value of the <see cref="DownloadYui"/> property. + /// The viewstate key to use for storing the value of the <see cref="DownloadYahooUILibrary"/> property. /// </summary> - private const string DownloadYuiViewStateKey = "DownloadYui"; + private const string DownloadYahooUILibraryViewStateKey = "DownloadYahooUILibrary"; #endregion #region Property defaults /// <summary> - /// The default value for the <see cref="AutoPostback"/> property. + /// The default value for the <see cref="AutoPostBack"/> property. /// </summary> - private const bool AutoPostbackDefault = false; + private const bool AutoPostBackDefault = false; /// <summary> /// The default value for the <see cref="Columns"/> property. @@ -256,9 +256,9 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { private const string RetryTextDefault = "RETRY"; /// <summary> - /// The default vlaue for the <see cref="DownloadYui"/> property. + /// The default vlaue for the <see cref="DownloadYahooUILibrary"/> property. /// </summary> - private const bool DownloadYuiDefault = true; + private const bool DownloadYahooUILibraryDefault = true; #endregion @@ -334,19 +334,19 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <summary> /// Gets or sets a value indicating whether a postback is made to fire the - /// <see cref="LoggedIn"/> event as soon as authentication has completed + /// <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> event as soon as authentication has completed /// successfully. /// </summary> /// <value> /// <c>true</c> if a postback should be made automatically upon authentication; - /// otherwise, <c>false</c> to delay the <see cref="LoggedIn"/> event from firing - /// at the server until a postback is made by some other control. + /// otherwise, <c>false</c> to delay the <see cref="OpenIdRelyingPartyControlBase.LoggedIn"/> + /// event from firing at the server until a postback is made by some other control. /// </value> - [Bindable(true), Category(BehaviorCategory), DefaultValue(AutoPostbackDefault)] + [Bindable(true), Category(BehaviorCategory), DefaultValue(AutoPostBackDefault)] [Description("Whether the LoggedIn event fires on the server as soon as authentication completes successfully.")] - public bool AutoPostback { - get { return (bool)(this.ViewState[AutoPostbackViewStateKey] ?? AutoPostbackDefault); } - set { this.ViewState[AutoPostbackViewStateKey] = value; } + public bool AutoPostBack { + get { return (bool)(this.ViewState[AutoPostBackViewStateKey] ?? AutoPostBackDefault); } + set { this.ViewState[AutoPostBackViewStateKey] = value; } } /// <summary> @@ -569,11 +569,11 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <remarks> /// The split button brings in about 180KB of YUI javascript dependencies. /// </remarks> - [Bindable(true), DefaultValue(DownloadYuiDefault), Category(BehaviorCategory)] + [Bindable(true), DefaultValue(DownloadYahooUILibraryDefault), Category(BehaviorCategory)] [Description("Whether a split button will be used for the \"log in\" when the user provides an identifier that delegates to more than one Provider.")] - public bool DownloadYui { - get { return (bool)(this.ViewState[DownloadYuiViewStateKey] ?? DownloadYuiDefault); } - set { this.ViewState[DownloadYuiViewStateKey] = value; } + public bool DownloadYahooUILibrary { + get { return (bool)(this.ViewState[DownloadYahooUILibraryViewStateKey] ?? DownloadYahooUILibraryDefault); } + set { this.ViewState[DownloadYahooUILibraryViewStateKey] = value; } } #endregion @@ -632,6 +632,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// When implemented by a class, enables a server control to process an event raised when a form is posted to the server. /// </summary> /// <param name="eventArgument">A <see cref="T:System.String"/> that represents an optional event argument to be passed to the event handler.</param> + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Signature predefined.")] void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) { this.RaisePostBackEvent(eventArgument); } @@ -663,7 +664,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); - if (this.DownloadYui) { + if (this.DownloadYahooUILibrary) { string yuiLoadScript = @"var loader = new YAHOO.util.YUILoader({ require: ['button', 'menu'], loadOptional: false, @@ -753,7 +754,7 @@ loader.insert();"; /// <summary> /// When implemented by a class, signals the server control to notify the ASP.NET application that the state of the control has changed. /// </summary> - [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Preserve signature of interface we're implementing.")] + [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Predefined signature.")] protected virtual void RaisePostDataChangedEvent() { this.OnTextChanged(); } @@ -762,6 +763,7 @@ loader.insert();"; /// When implemented by a class, enables a server control to process an event raised when a form is posted to the server. /// </summary> /// <param name="eventArgument">A <see cref="T:System.String"/> that represents an optional event argument to be passed to the event handler.</param> + [SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate", Justification = "Preserve signature of interface we're implementing.")] protected virtual void RaisePostBackEvent(string eventArgument) { } @@ -807,7 +809,7 @@ loader.insert();"; MessagingUtilities.GetSafeJavascriptValue(this.AuthenticationSucceededToolTip), MessagingUtilities.GetSafeJavascriptValue(this.AuthenticatedAsToolTip), MessagingUtilities.GetSafeJavascriptValue(this.AuthenticationFailedToolTip), - this.AutoPostback ? Page.ClientScript.GetPostBackEventReference(this, null) : null, + this.AutoPostBack ? Page.ClientScript.GetPostBackEventReference(this, null) : null, Environment.NewLine); startupScript.AppendLine("</script>"); |