From a047a2c914d4d99cad5777e2267bccdc1f46a409 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 4 Oct 2022 17:10:16 -0700 Subject: [PATCH 01/14] Improve IFormCollection.Items documentation Fixes #36712 --- src/Http/Http.Features/src/IFormCollection.cs | 14 ++++++++++++++ src/Http/Http/src/Features/FormFeature.cs | 4 ++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Http/Http.Features/src/IFormCollection.cs b/src/Http/Http.Features/src/IFormCollection.cs index 1a2788bb234f..d52c5bd05201 100644 --- a/src/Http/Http.Features/src/IFormCollection.cs +++ b/src/Http/Http.Features/src/IFormCollection.cs @@ -77,10 +77,24 @@ public interface IFormCollection : IEnumerable /// key is null. /// + /// + /// incorrect content-type. + /// /// + /// /// has a different indexer contract than /// , as it will return StringValues.Empty for missing entries /// rather than throwing an Exception. + /// + /// + /// This indexer can only be used on POST requests. Otherwise an exception of type + /// is thrown. + /// + /// + /// Invoking this property could result in thread exhaustion since it's wrapping an asynchronous implementation. + /// To prevent this the method can be used. + /// For more information please read https://devblogs.microsoft.com/pfxteam/should-i-expose-synchronous-wrappers-for-asynchronous-methods/. + /// /// StringValues this[string key] { get; } diff --git a/src/Http/Http/src/Features/FormFeature.cs b/src/Http/Http/src/Features/FormFeature.cs index 3be60e7fe142..a6dca07c949f 100644 --- a/src/Http/Http/src/Features/FormFeature.cs +++ b/src/Http/Http/src/Features/FormFeature.cs @@ -101,10 +101,10 @@ public IFormCollection ReadForm() if (!HasFormContentType) { - throw new InvalidOperationException("Incorrect Content-Type: " + _request.ContentType); + throw new InvalidOperationException("Form Collection properties can only be accessed from a POST request"); } - // TODO: Issue #456 Avoid Sync-over-Async http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx + // TODO: Issue #456 Avoid Sync-over-Async https://devblogs.microsoft.com/pfxteam/should-i-expose-synchronous-wrappers-for-asynchronous-methods/ // TODO: How do we prevent thread exhaustion? return ReadFormAsync().GetAwaiter().GetResult(); } From c713ec29c668181eaba2323ecf8f73136f8491e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Wed, 5 Oct 2022 11:19:11 -0700 Subject: [PATCH 02/14] Update IFormCollection.cs --- src/Http/Http.Features/src/IFormCollection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Http/Http.Features/src/IFormCollection.cs b/src/Http/Http.Features/src/IFormCollection.cs index d52c5bd05201..f104fea49345 100644 --- a/src/Http/Http.Features/src/IFormCollection.cs +++ b/src/Http/Http.Features/src/IFormCollection.cs @@ -93,7 +93,7 @@ public interface IFormCollection : IEnumerable /// Invoking this property could result in thread exhaustion since it's wrapping an asynchronous implementation. /// To prevent this the method can be used. - /// For more information please read https://devblogs.microsoft.com/pfxteam/should-i-expose-synchronous-wrappers-for-asynchronous-methods/. + /// For more information please read https://aka.ms/aspnet/forms-async /// /// StringValues this[string key] { get; } From 8c59e48ce33024f03d7d1d453b7367e99eea2e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Wed, 5 Oct 2022 15:00:00 -0700 Subject: [PATCH 03/14] Update FormFeature.cs --- src/Http/Http/src/Features/FormFeature.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Http/Http/src/Features/FormFeature.cs b/src/Http/Http/src/Features/FormFeature.cs index a6dca07c949f..c0496c24b0d9 100644 --- a/src/Http/Http/src/Features/FormFeature.cs +++ b/src/Http/Http/src/Features/FormFeature.cs @@ -101,11 +101,10 @@ public IFormCollection ReadForm() if (!HasFormContentType) { - throw new InvalidOperationException("Form Collection properties can only be accessed from a POST request"); + throw new InvalidOperationException("This request does not have a Content-Type header. Forms are available from requests with bodies like POSTs and a form Content-Type of either application/x-www-form-urlencoded or multipart/form-data."); } - // TODO: Issue #456 Avoid Sync-over-Async https://devblogs.microsoft.com/pfxteam/should-i-expose-synchronous-wrappers-for-asynchronous-methods/ - // TODO: How do we prevent thread exhaustion? + // c.f., https://aka.ms/aspnet/forms-async return ReadFormAsync().GetAwaiter().GetResult(); } From 7cb20e17011a1dd3906fe0fe7346531221fae884 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Wed, 5 Oct 2022 17:05:56 -0700 Subject: [PATCH 04/14] Fix link --- src/Http/Http.Features/src/IFormCollection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Http/Http.Features/src/IFormCollection.cs b/src/Http/Http.Features/src/IFormCollection.cs index f104fea49345..d0cf43f5518a 100644 --- a/src/Http/Http.Features/src/IFormCollection.cs +++ b/src/Http/Http.Features/src/IFormCollection.cs @@ -93,7 +93,7 @@ public interface IFormCollection : IEnumerable /// Invoking this property could result in thread exhaustion since it's wrapping an asynchronous implementation. /// To prevent this the method can be used. - /// For more information please read https://aka.ms/aspnet/forms-async + /// For more information, see . /// /// StringValues this[string key] { get; } From d17f09f6a57093866c0b95e7ea39579bbfdac72b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Tue, 11 Oct 2022 16:31:37 -0700 Subject: [PATCH 05/14] Fix XML syntax --- src/Http/Http.Features/src/IFormCollection.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Http/Http.Features/src/IFormCollection.cs b/src/Http/Http.Features/src/IFormCollection.cs index d0cf43f5518a..eb70b27ab7c3 100644 --- a/src/Http/Http.Features/src/IFormCollection.cs +++ b/src/Http/Http.Features/src/IFormCollection.cs @@ -92,8 +92,8 @@ public interface IFormCollection : IEnumerable /// /// Invoking this property could result in thread exhaustion since it's wrapping an asynchronous implementation. - /// To prevent this the method can be used. - /// For more information, see . + /// To prevent this the method can be used. + /// For more information, see . /// /// StringValues this[string key] { get; } From c69050a74736aaebb5790ab6938742fcdd02f813 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 11 Oct 2022 16:37:11 -0700 Subject: [PATCH 06/14] Add remark to HttpRequest.Form --- src/Http/Http.Abstractions/src/HttpRequest.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Http/Http.Abstractions/src/HttpRequest.cs b/src/Http/Http.Abstractions/src/HttpRequest.cs index dd0c27f35417..abf9ae04cd0d 100644 --- a/src/Http/Http.Abstractions/src/HttpRequest.cs +++ b/src/Http/Http.Abstractions/src/HttpRequest.cs @@ -115,6 +115,13 @@ public abstract class HttpRequest /// /// Gets or sets the request body as a form. /// + /// + /// + /// Invoking this property could result in thread exhaustion since it's wrapping an asynchronous implementation. + /// To prevent this the method can be used. + /// For more information, see . + /// + /// public abstract IFormCollection Form { get; set; } /// From 4acb483195627ba8dfa38497e333601d13db1ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Fri, 14 Oct 2022 15:23:27 -0700 Subject: [PATCH 07/14] Add exception summary --- src/Http/Http.Abstractions/src/HttpRequest.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Http/Http.Abstractions/src/HttpRequest.cs b/src/Http/Http.Abstractions/src/HttpRequest.cs index abf9ae04cd0d..3c94d4ae1e32 100644 --- a/src/Http/Http.Abstractions/src/HttpRequest.cs +++ b/src/Http/Http.Abstractions/src/HttpRequest.cs @@ -115,6 +115,9 @@ public abstract class HttpRequest /// /// Gets or sets the request body as a form. /// + /// + /// incorrect content-type. + /// /// /// /// Invoking this property could result in thread exhaustion since it's wrapping an asynchronous implementation. @@ -127,6 +130,9 @@ public abstract class HttpRequest /// /// Reads the request body if it is a form. /// + /// + /// incorrect content-type. + /// /// public abstract Task ReadFormAsync(CancellationToken cancellationToken = new CancellationToken()); From 89d0f6d442fbb46a247199d0b7b262a1f3746406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Fri, 14 Oct 2022 15:35:35 -0700 Subject: [PATCH 08/14] Fix method reference in doc --- src/Http/Http.Features/src/IFormCollection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Http/Http.Features/src/IFormCollection.cs b/src/Http/Http.Features/src/IFormCollection.cs index eb70b27ab7c3..c639c7c1e52a 100644 --- a/src/Http/Http.Features/src/IFormCollection.cs +++ b/src/Http/Http.Features/src/IFormCollection.cs @@ -92,7 +92,7 @@ public interface IFormCollection : IEnumerable /// /// Invoking this property could result in thread exhaustion since it's wrapping an asynchronous implementation. - /// To prevent this the method can be used. + /// To prevent this the method can be used. /// For more information, see . /// /// From 71ccec35188e5ef3d1bf518349e8f57c633ece79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Thu, 23 Mar 2023 11:13:21 -0700 Subject: [PATCH 09/14] Update IFormCollection.cs --- src/Http/Http.Features/src/IFormCollection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Http/Http.Features/src/IFormCollection.cs b/src/Http/Http.Features/src/IFormCollection.cs index c639c7c1e52a..eb70b27ab7c3 100644 --- a/src/Http/Http.Features/src/IFormCollection.cs +++ b/src/Http/Http.Features/src/IFormCollection.cs @@ -92,7 +92,7 @@ public interface IFormCollection : IEnumerable /// /// Invoking this property could result in thread exhaustion since it's wrapping an asynchronous implementation. - /// To prevent this the method can be used. + /// To prevent this the method can be used. /// For more information, see . /// /// From a0cda872e7fddec59d312f7f706c02dde42088da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Thu, 23 Mar 2023 15:12:14 -0700 Subject: [PATCH 10/14] Update IFormCollection.cs --- src/Http/Http.Features/src/IFormCollection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Http/Http.Features/src/IFormCollection.cs b/src/Http/Http.Features/src/IFormCollection.cs index eb70b27ab7c3..7da5c26d41e7 100644 --- a/src/Http/Http.Features/src/IFormCollection.cs +++ b/src/Http/Http.Features/src/IFormCollection.cs @@ -92,7 +92,7 @@ public interface IFormCollection : IEnumerable /// /// Invoking this property could result in thread exhaustion since it's wrapping an asynchronous implementation. - /// To prevent this the method can be used. + /// To prevent this the method can be used. /// For more information, see . /// /// From 2fcbd03f922e7a782c6d43f2b0ae6b27e4137bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Mon, 27 Mar 2023 10:37:27 -0700 Subject: [PATCH 11/14] Update src/Http/Http.Abstractions/src/HttpRequest.cs Co-authored-by: Safia Abdalla --- src/Http/Http.Abstractions/src/HttpRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Http/Http.Abstractions/src/HttpRequest.cs b/src/Http/Http.Abstractions/src/HttpRequest.cs index 3c94d4ae1e32..7d710b766671 100644 --- a/src/Http/Http.Abstractions/src/HttpRequest.cs +++ b/src/Http/Http.Abstractions/src/HttpRequest.cs @@ -121,7 +121,7 @@ public abstract class HttpRequest /// /// /// Invoking this property could result in thread exhaustion since it's wrapping an asynchronous implementation. - /// To prevent this the method can be used. + /// To prevent this the method can be used. /// For more information, see . /// /// From eb205beb8aacd160cb649d6d40b7d11315e1fde0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Mon, 27 Mar 2023 16:28:22 -0700 Subject: [PATCH 12/14] Update src/Http/Http.Features/src/IFormCollection.cs Co-authored-by: James Newton-King --- src/Http/Http.Features/src/IFormCollection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Http/Http.Features/src/IFormCollection.cs b/src/Http/Http.Features/src/IFormCollection.cs index 7da5c26d41e7..594c2b88de38 100644 --- a/src/Http/Http.Features/src/IFormCollection.cs +++ b/src/Http/Http.Features/src/IFormCollection.cs @@ -92,7 +92,7 @@ public interface IFormCollection : IEnumerable /// /// Invoking this property could result in thread exhaustion since it's wrapping an asynchronous implementation. - /// To prevent this the method can be used. + /// To prevent this the method can be used. /// For more information, see . /// /// From da246a6b42a1b025641e66441c63b995e1739fba Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Tue, 28 Mar 2023 08:35:43 +0800 Subject: [PATCH 13/14] Update src/Http/Http.Features/src/IFormCollection.cs --- src/Http/Http.Features/src/IFormCollection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Http/Http.Features/src/IFormCollection.cs b/src/Http/Http.Features/src/IFormCollection.cs index 594c2b88de38..83a648b3d1c2 100644 --- a/src/Http/Http.Features/src/IFormCollection.cs +++ b/src/Http/Http.Features/src/IFormCollection.cs @@ -92,7 +92,7 @@ public interface IFormCollection : IEnumerable /// /// Invoking this property could result in thread exhaustion since it's wrapping an asynchronous implementation. - /// To prevent this the method can be used. + /// To prevent this the method can be used. /// For more information, see . /// /// From d734917d631c1c19808df320d091508124b5e08b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Ros?= Date: Mon, 27 Mar 2023 18:08:31 -0700 Subject: [PATCH 14/14] Update src/Http/Http.Features/src/IFormCollection.cs Co-authored-by: James Newton-King --- src/Http/Http.Features/src/IFormCollection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Http/Http.Features/src/IFormCollection.cs b/src/Http/Http.Features/src/IFormCollection.cs index 83a648b3d1c2..e9c5475b4d10 100644 --- a/src/Http/Http.Features/src/IFormCollection.cs +++ b/src/Http/Http.Features/src/IFormCollection.cs @@ -92,7 +92,7 @@ public interface IFormCollection : IEnumerable /// /// Invoking this property could result in thread exhaustion since it's wrapping an asynchronous implementation. - /// To prevent this the method can be used. + /// The HttpRequest.ReadFormAsync(CancellationToken) method can get the form without blocking. /// For more information, see . /// ///