Skip to content

Commit 1d8d330

Browse files
committed
Use Encoding.CreateTranscodingStream
Fixes #21243
1 parent 4ebf695 commit 1d8d330

9 files changed

+46
-784
lines changed

src/Mvc/Mvc.Core/src/Formatters/SystemTextJsonInputFormatter.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using System.Text.Json;
88
using System.Threading.Tasks;
99
using Microsoft.AspNetCore.Http;
10-
using Microsoft.AspNetCore.Mvc.Formatters.Json;
1110
using Microsoft.Extensions.Logging;
1211

1312
namespace Microsoft.AspNetCore.Mvc.Formatters
@@ -67,7 +66,7 @@ public sealed override async Task<InputFormatterResult> ReadRequestBodyAsync(
6766
}
6867

6968
var httpContext = context.HttpContext;
70-
var inputStream = GetInputStream(httpContext, encoding);
69+
var (inputStream, usesTranscodingStream) = GetInputStream(httpContext, encoding);
7170

7271
object model;
7372
try
@@ -98,9 +97,9 @@ public sealed override async Task<InputFormatterResult> ReadRequestBodyAsync(
9897
}
9998
finally
10099
{
101-
if (inputStream is TranscodingReadStream transcoding)
100+
if (usesTranscodingStream)
102101
{
103-
await transcoding.DisposeAsync();
102+
await inputStream.DisposeAsync();
104103
}
105104
}
106105

@@ -119,14 +118,15 @@ public sealed override async Task<InputFormatterResult> ReadRequestBodyAsync(
119118
}
120119
}
121120

122-
private Stream GetInputStream(HttpContext httpContext, Encoding encoding)
121+
private (Stream inputStream, bool usesTranscodingStream) GetInputStream(HttpContext httpContext, Encoding encoding)
123122
{
124123
if (encoding.CodePage == Encoding.UTF8.CodePage)
125124
{
126-
return httpContext.Request.Body;
125+
return (httpContext.Request.Body, false);
127126
}
128127

129-
return new TranscodingReadStream(httpContext.Request.Body, encoding);
128+
var inputStream = Encoding.CreateTranscodingStream(httpContext.Request.Body, encoding, Encoding.UTF8, leaveOpen: true);
129+
return (inputStream, true);
130130
}
131131

132132
private static class Log

src/Mvc/Mvc.Core/src/Formatters/SystemTextJsonOutputFormatter.cs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
using System.Text;
77
using System.Text.Encodings.Web;
88
using System.Text.Json;
9-
using System.Threading;
109
using System.Threading.Tasks;
1110
using Microsoft.AspNetCore.Http;
12-
using Microsoft.AspNetCore.Mvc.Formatters.Json;
1311

1412
namespace Microsoft.AspNetCore.Mvc.Formatters
1513
{
@@ -73,7 +71,8 @@ public sealed override async Task WriteResponseBodyAsync(OutputFormatterWriteCon
7371

7472
var httpContext = context.HttpContext;
7573

76-
var writeStream = GetWriteStream(httpContext, selectedEncoding);
74+
var (writeStream, usesTranscodingStream) = GetWriteStream(httpContext, selectedEncoding);
75+
7776
try
7877
{
7978
// context.ObjectType reflects the declared model type when specified.
@@ -82,35 +81,29 @@ public sealed override async Task WriteResponseBodyAsync(OutputFormatterWriteCon
8281
// the behavior you get when the user does not declare the return type and with Json.Net at least at the top level.
8382
var objectType = context.Object?.GetType() ?? context.ObjectType ?? typeof(object);
8483
await JsonSerializer.SerializeAsync(writeStream, context.Object, objectType, SerializerOptions);
85-
86-
// The transcoding streams use Encoders and Decoders that have internal buffers. We need to flush these
87-
// when there is no more data to be written. Stream.FlushAsync isn't suitable since it's
88-
// acceptable to Flush a Stream (multiple times) prior to completion.
89-
if (writeStream is TranscodingWriteStream transcodingStream)
90-
{
91-
await transcodingStream.FinalWriteAsync(CancellationToken.None);
92-
}
9384
await writeStream.FlushAsync();
9485
}
9586
finally
9687
{
97-
if (writeStream is TranscodingWriteStream transcodingStream)
88+
if (usesTranscodingStream)
9889
{
99-
await transcodingStream.DisposeAsync();
90+
await writeStream.DisposeAsync();
10091
}
10192
}
93+
10294
}
10395

104-
private Stream GetWriteStream(HttpContext httpContext, Encoding selectedEncoding)
96+
private (Stream writeStream, bool usesTranscodingStream) GetWriteStream(HttpContext httpContext, Encoding selectedEncoding)
10597
{
10698
if (selectedEncoding.CodePage == Encoding.UTF8.CodePage)
10799
{
108100
// JsonSerializer does not write a BOM. Therefore we do not have to handle it
109101
// in any special way.
110-
return httpContext.Response.Body;
102+
return (httpContext.Response.Body, false);
111103
}
112104

113-
return new TranscodingWriteStream(httpContext.Response.Body, selectedEncoding);
105+
var writeStream = Encoding.CreateTranscodingStream(httpContext.Response.Body, selectedEncoding, Encoding.UTF8, leaveOpen: true);
106+
return (writeStream, true);
114107
}
115108
}
116109
}

src/Mvc/Mvc.Core/src/Formatters/TranscodingReadStream.cs

Lines changed: 0 additions & 223 deletions
This file was deleted.

0 commit comments

Comments
 (0)