Skip to content

Instantly share code, notes, and snippets.

@akunzai
Last active December 29, 2017 07:49
Show Gist options
  • Save akunzai/3000ba64ee3621aa5bf85bc6de94c54f to your computer and use it in GitHub Desktop.
Save akunzai/3000ba64ee3621aa5bf85bc6de94c54f to your computer and use it in GitHub Desktop.
alternative FormUrlEncodedContent that support large context
using System.Collections.Generic;
using System.Net.Http.Headers;
using System.Text;
namespace System.Net.Http
{
/// <summary>
/// alternative <see cref="FormUrlEncodedContent"/> implementation that support large context
/// to prevent <see cref="UriFormatException"/> Invalid URI: The Uri string is too long. error
/// </summary>
public class LargeFormUrlEncodedContent : ByteArrayContent
{
/// <summary>
/// Uri.EscapeDataString max length allowed:
/// .NET &lt; 4.5 = 32765,
/// .NET &gt;= 4.5 = 65519
/// </summary>
public static int MaxLengthAllowed { get; set; } = 32765;
/// <summary>
/// ISO-8859-1 encoding
/// </summary>
public static Encoding Encoding { get; set; } = Encoding.GetEncoding(28591);
public LargeFormUrlEncodedContent(
IEnumerable<KeyValuePair<string, string>> nameValueCollection) :
base(GetContentByteArray((nameValueCollection)))
{
this.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
}
private static byte[] GetContentByteArray(IEnumerable<KeyValuePair<string, string>> nameValueCollection)
{
if (nameValueCollection == null)
throw new ArgumentNullException(nameof(nameValueCollection));
var stringBuilder = new StringBuilder();
foreach (var nameValue in nameValueCollection)
{
if (stringBuilder.Length > 0)
stringBuilder.Append('&');
stringBuilder.Append(Encode(nameValue.Key));
stringBuilder.Append('=');
stringBuilder.Append(Encode(nameValue.Value));
}
return Encoding.GetBytes(stringBuilder.ToString());
}
private static string Encode(string data)
{
if (string.IsNullOrEmpty(data))
return string.Empty;
var stringBuilder = new StringBuilder();
var loops = data.Length / MaxLengthAllowed;
for (var i = 0; i <= loops; i++)
{
var truncatedData = i < loops
? data.Substring(MaxLengthAllowed * i, MaxLengthAllowed)
: data.Substring(MaxLengthAllowed * i);
stringBuilder.Append(Uri.EscapeDataString(truncatedData).Replace("%20", "+"));
}
return stringBuilder.ToString();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment