Skip to content

Commit f132942

Browse files
authored
First try at implementing newly suggested ctor for providing tighter control over charset (#63231)
* First try at implementing newly suggested ctor for providing tighter control over charset * Update reference assembly so mediaType is accurate * Update per github code review
1 parent 0a68428 commit f132942

File tree

4 files changed

+90
-9
lines changed

4 files changed

+90
-9
lines changed

src/libraries/System.Net.Http/ref/System.Net.Http.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,10 @@ protected override void SerializeToStream(System.IO.Stream stream, System.Net.Tr
437437
public partial class StringContent : System.Net.Http.ByteArrayContent
438438
{
439439
public StringContent(string content) : base (default(byte[])) { }
440+
public StringContent(string content, System.Net.Http.Headers.MediaTypeHeaderValue mediaType) : base (default(byte[])) { }
440441
public StringContent(string content, System.Text.Encoding? encoding) : base (default(byte[])) { }
441-
public StringContent(string content, System.Text.Encoding? encoding, string? mediaType) : base (default(byte[])) { }
442+
public StringContent(string content, System.Text.Encoding? encoding, System.Net.Http.Headers.MediaTypeHeaderValue mediaType) : base (default(byte[])) { }
443+
public StringContent(string content, System.Text.Encoding? encoding, string mediaType) : base (default(byte[])) { }
442444
protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { throw null; }
443445
}
444446
}
@@ -692,6 +694,7 @@ public partial class MediaTypeHeaderValue : System.ICloneable
692694
{
693695
protected MediaTypeHeaderValue(System.Net.Http.Headers.MediaTypeHeaderValue source) { }
694696
public MediaTypeHeaderValue(string mediaType) { }
697+
public MediaTypeHeaderValue(string mediaType, string? charSet) { }
695698
public string? CharSet { get { throw null; } set { } }
696699
[System.Diagnostics.CodeAnalysis.DisallowNullAttribute]
697700
public string? MediaType { get { throw null; } set { } }

src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderValue.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,19 @@ protected MediaTypeHeaderValue(MediaTypeHeaderValue source)
8080
}
8181

8282
public MediaTypeHeaderValue(string mediaType)
83+
: this(mediaType, charSet: null)
84+
{
85+
}
86+
87+
public MediaTypeHeaderValue(string mediaType, string? charSet)
8388
{
8489
CheckMediaTypeFormat(mediaType, nameof(mediaType));
8590
_mediaType = mediaType;
91+
92+
if (!string.IsNullOrEmpty(charSet))
93+
{
94+
CharSet = charSet;
95+
}
8696
}
8797

8898
public override string ToString()

src/libraries/System.Net.Http/src/System/Net/Http/StringContent.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,29 @@ public class StringContent : ByteArrayContent
1414
private const string DefaultMediaType = "text/plain";
1515

1616
public StringContent(string content)
17-
: this(content, null, null)
17+
: this(content, DefaultStringEncoding, DefaultMediaType)
18+
{
19+
}
20+
21+
public StringContent(string content, MediaTypeHeaderValue mediaType)
22+
: this(content, DefaultStringEncoding, mediaType)
1823
{
1924
}
2025

2126
public StringContent(string content, Encoding? encoding)
22-
: this(content, encoding, null)
27+
: this(content, encoding, DefaultMediaType)
2328
{
2429
}
2530

26-
public StringContent(string content, Encoding? encoding, string? mediaType)
27-
: base(GetContentByteArray(content, encoding))
31+
public StringContent(string content, Encoding? encoding, string mediaType)
32+
: this(content, encoding, new MediaTypeHeaderValue(mediaType, (encoding ?? DefaultStringEncoding).WebName))
2833
{
29-
// Initialize the 'Content-Type' header with information provided by parameters.
30-
MediaTypeHeaderValue headerValue = new MediaTypeHeaderValue((mediaType == null) ? DefaultMediaType : mediaType);
31-
headerValue.CharSet = (encoding == null) ? HttpContent.DefaultStringEncoding.WebName : encoding.WebName;
34+
}
3235

33-
Headers.ContentType = headerValue;
36+
public StringContent(string content, Encoding? encoding, MediaTypeHeaderValue mediaType)
37+
: base(GetContentByteArray(content, encoding))
38+
{
39+
Headers.ContentType = mediaType;
3440
}
3541

3642
// A StringContent is essentially a ByteArrayContent. We serialize the string into a byte-array in the

src/libraries/System.Net.Http/tests/FunctionalTests/StringContentTest.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,67 @@ public async Task Ctor_DefineNoEncoding_DefaultEncodingUsed()
7070
string roundTrip = new StreamReader(destination, defaultStringEncoding).ReadToEnd();
7171
Assert.Equal(sourceString, roundTrip);
7272
}
73+
74+
[Fact]
75+
public async Task Ctor_UseCustomMediaTypeHeaderValue_SpecificEncoding()
76+
{
77+
// Use UTF-8 encoding to serialize a chinese string.
78+
string sourceString = "\u4f1a\u5458\u670d\u52a1";
79+
80+
var mediaTypeHeaderValue = new Headers.MediaTypeHeaderValue("application/custom", Encoding.UTF8.WebName);
81+
82+
var content = new StringContent(sourceString, Encoding.UTF8, mediaTypeHeaderValue);
83+
84+
Assert.Equal("application/custom", content.Headers.ContentType.MediaType);
85+
Assert.Equal("utf-8", content.Headers.ContentType.CharSet);
86+
87+
var destination = new MemoryStream(12);
88+
await content.CopyToAsync(destination);
89+
90+
string destinationString = Encoding.UTF8.GetString(destination.ToArray(), 0, (int)destination.Length);
91+
92+
Assert.Equal(sourceString, destinationString);
93+
}
94+
95+
[Fact]
96+
public async Task Ctor_UseCustomMediaTypeHeaderValue()
97+
{
98+
// Use UTF-8 encoding to serialize a chinese string.
99+
string sourceString = "\u4f1a\u5458\u670d\u52a1";
100+
101+
var mediaTypeHeaderValue = new Headers.MediaTypeHeaderValue("application/custom", Encoding.UTF8.WebName);
102+
103+
var content = new StringContent(sourceString, mediaTypeHeaderValue);
104+
105+
Assert.Equal("application/custom", content.Headers.ContentType.MediaType);
106+
Assert.Equal("utf-8", content.Headers.ContentType.CharSet);
107+
108+
var destination = new MemoryStream(12);
109+
await content.CopyToAsync(destination);
110+
111+
string destinationString = Encoding.UTF8.GetString(destination.ToArray(), 0, (int)destination.Length);
112+
113+
Assert.Equal(sourceString, destinationString);
114+
}
115+
116+
[Fact]
117+
public async Task Ctor_UseSpecificEncodingAndContentType()
118+
{
119+
// Use UTF-8 encoding to serialize a chinese string.
120+
string sourceString = "\u4f1a\u5458\u670d\u52a1";
121+
string contentType = "application/custom";
122+
123+
var content = new StringContent(sourceString, Encoding.UTF8, contentType);
124+
125+
Assert.Equal("application/custom", content.Headers.ContentType.MediaType);
126+
Assert.Equal("utf-8", content.Headers.ContentType.CharSet);
127+
128+
var destination = new MemoryStream(12);
129+
await content.CopyToAsync(destination);
130+
131+
string destinationString = Encoding.UTF8.GetString(destination.ToArray(), 0, (int)destination.Length);
132+
133+
Assert.Equal(sourceString, destinationString);
134+
}
73135
}
74136
}

0 commit comments

Comments
 (0)