diff --git a/src/Flurl.CodeGen/Metadata.cs b/src/Flurl.CodeGen/Metadata.cs index 0bf9f392..0e5f3067 100644 --- a/src/Flurl.CodeGen/Metadata.cs +++ b/src/Flurl.CodeGen/Metadata.cs @@ -125,6 +125,9 @@ public static IEnumerable GetRequestReturningExtensions(MethodA yield return Create("WithCookies", "Creates a new FlurlRequest and adds name-value pairs to its Cookie header based on property names/values of the provided object, or keys/values if object is a dictionary. " + "To automatically maintain a cookie \"session\", consider using a CookieJar or CookieSession instead.") .AddArg("values", "object", "Names/values of HTTP cookies to set. Typically an anonymous object or IDictionary."); + yield return Create("WithCookies", "Creates a new FlurlRequest and adds name-value pairs to its Cookie header. " + + "To automatically maintain a cookie \"session\", consider using a CookieJar or CookieSession instead.") + .AddArg("values", "IEnumerable<(string Key, string Value)>", "Names/values of HTTP cookies to set."); yield return Create("WithCookies", "Creates a new FlurlRequest and sets the CookieJar associated with this request, which will be updated with any Set-Cookie headers present in the response and is suitable for reuse in subsequent requests.") .AddArg("cookieJar", "CookieJar", "The CookieJar."); yield return Create("WithCookies", "Creates a new FlurlRequest and associates it with a new CookieJar, which will be updated with any Set-Cookie headers present in the response and is suitable for reuse in subsequent requests.") diff --git a/src/Flurl.CodeGen/Program.cs b/src/Flurl.CodeGen/Program.cs index db0da26a..4babfe3f 100644 --- a/src/Flurl.CodeGen/Program.cs +++ b/src/Flurl.CodeGen/Program.cs @@ -50,6 +50,7 @@ static int Main(string[] args) { writer .WriteLine("// This file was auto-generated by Flurl.CodeGen. Do not edit directly.") .WriteLine("using System;") + .WriteLine("using System.Collections.Generic;") .WriteLine("using System.IO;") .WriteLine("using System.Net;") .WriteLine("using System.Net.Http;") diff --git a/src/Flurl.Http/CookieExtensions.cs b/src/Flurl.Http/CookieExtensions.cs index beaa5bab..997f4862 100644 --- a/src/Flurl.Http/CookieExtensions.cs +++ b/src/Flurl.Http/CookieExtensions.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Linq; using Flurl.Util; @@ -30,15 +31,31 @@ public static IFlurlRequest WithCookie(this IFlurlRequest request, string name, /// The IFlurlRequest. /// Names/values of HTTP cookies to set. Typically an anonymous object or IDictionary. /// This IFlurlClient. - public static IFlurlRequest WithCookies(this IFlurlRequest request, object values) { + public static IFlurlRequest WithCookies(this IFlurlRequest request, object values) + { + var kvPairs = values.ToKeyValuePairs() + .Select(kv => (kv.Key, kv.Value.ToInvariantString())); + return request.WithCookies(kvPairs); + } + + /// + /// Adds or updates name-value pairs in this request's Cookie header. + /// To automatically maintain a cookie "session", consider using a CookieJar or CookieSession instead. + /// + /// The IFlurlRequest. + /// Names/values of HTTP cookies to set. + /// This IFlurlClient. + public static IFlurlRequest WithCookies(this IFlurlRequest request, IEnumerable<(string Key, string Value)> values) + { var cookies = new NameValueList(request.Cookies, true); // cookie names are case-sensitive https://stackoverflow.com/a/11312272/62600 // although rare, we need to accommodate the possibility of multiple cookies with the same name - foreach (var group in values.ToKeyValuePairs().GroupBy(x => x.Key)) { + foreach (var group in values.GroupBy(x => x.Key)) + { // add or replace the first one (by name) - cookies.AddOrReplace(group.Key, group.First().Value.ToInvariantString()); + cookies.AddOrReplace(group.Key, group.First().Value); // append the rest foreach (var kv in group.Skip(1)) - cookies.Add(kv.Key, kv.Value.ToInvariantString()); + cookies.Add(kv.Key, kv.Value); } return request.WithHeader("Cookie", CookieCutter.BuildRequestHeader(cookies)); } diff --git a/src/Flurl.Http/GeneratedExtensions.cs b/src/Flurl.Http/GeneratedExtensions.cs index 75b39ab3..68806e44 100644 --- a/src/Flurl.Http/GeneratedExtensions.cs +++ b/src/Flurl.Http/GeneratedExtensions.cs @@ -1,5 +1,6 @@ // This file was auto-generated by Flurl.CodeGen. Do not edit directly. using System; +using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Http; @@ -632,6 +633,16 @@ public static IFlurlRequest WithCookies(this Url url, object values) { return new FlurlRequest(url).WithCookies(values); } + /// + /// Creates a new FlurlRequest and adds name-value pairs to its Cookie header. To automatically maintain a cookie "session", consider using a CookieJar or CookieSession instead. + /// + /// This Flurl.Url. + /// Names/values of HTTP cookies to set. + /// A new IFlurlRequest. + public static IFlurlRequest WithCookies(this Url url, IEnumerable<(string Key, string Value)> values) { + return new FlurlRequest(url).WithCookies(values); + } + /// /// Creates a new FlurlRequest and sets the CookieJar associated with this request, which will be updated with any Set-Cookie headers present in the response and is suitable for reuse in subsequent requests. /// @@ -1151,6 +1162,16 @@ public static IFlurlRequest WithCookies(this string url, object values) { return new FlurlRequest(url).WithCookies(values); } + /// + /// Creates a new FlurlRequest and adds name-value pairs to its Cookie header. To automatically maintain a cookie "session", consider using a CookieJar or CookieSession instead. + /// + /// This URL. + /// Names/values of HTTP cookies to set. + /// A new IFlurlRequest. + public static IFlurlRequest WithCookies(this string url, IEnumerable<(string Key, string Value)> values) { + return new FlurlRequest(url).WithCookies(values); + } + /// /// Creates a new FlurlRequest and sets the CookieJar associated with this request, which will be updated with any Set-Cookie headers present in the response and is suitable for reuse in subsequent requests. /// @@ -1670,6 +1691,16 @@ public static IFlurlRequest WithCookies(this Uri uri, object values) { return new FlurlRequest(uri).WithCookies(values); } + /// + /// Creates a new FlurlRequest and adds name-value pairs to its Cookie header. To automatically maintain a cookie "session", consider using a CookieJar or CookieSession instead. + /// + /// This System.Uri. + /// Names/values of HTTP cookies to set. + /// A new IFlurlRequest. + public static IFlurlRequest WithCookies(this Uri uri, IEnumerable<(string Key, string Value)> values) { + return new FlurlRequest(uri).WithCookies(values); + } + /// /// Creates a new FlurlRequest and sets the CookieJar associated with this request, which will be updated with any Set-Cookie headers present in the response and is suitable for reuse in subsequent requests. ///