diff --git a/src/Http/WebUtilities/src/FileBufferingWriteStream.cs b/src/Http/WebUtilities/src/FileBufferingWriteStream.cs
index ee03685312..fd9c993bad 100644
--- a/src/Http/WebUtilities/src/FileBufferingWriteStream.cs
+++ b/src/Http/WebUtilities/src/FileBufferingWriteStream.cs
@@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.WebUtilities
public override bool CanWrite => true;
///
- public override long Length => throw new NotSupportedException();
+ public override long Length => PagedByteBuffer.Length + (FileStream?.Length ?? 0);
///
public override long Position
@@ -78,8 +78,6 @@ namespace Microsoft.AspNetCore.WebUtilities
set => throw new NotSupportedException();
}
- internal long BufferedLength => PagedByteBuffer.Length + (FileStream?.Length ?? 0);
-
internal PagedByteBuffer PagedByteBuffer { get; }
internal FileStream FileStream { get; private set; }
@@ -103,7 +101,7 @@ namespace Microsoft.AspNetCore.WebUtilities
ThrowArgumentException(buffer, offset, count);
ThrowIfDisposed();
- if (_bufferLimit.HasValue && _bufferLimit - BufferedLength < count)
+ if (_bufferLimit.HasValue && _bufferLimit - Length < count)
{
Dispose();
throw new IOException("Buffer limit exceeded.");
@@ -136,7 +134,7 @@ namespace Microsoft.AspNetCore.WebUtilities
ThrowArgumentException(buffer, offset, count);
ThrowIfDisposed();
- if (_bufferLimit.HasValue && _bufferLimit - BufferedLength < count)
+ if (_bufferLimit.HasValue && _bufferLimit - Length < count)
{
Dispose();
throw new IOException("Buffer limit exceeded.");
diff --git a/src/Http/WebUtilities/test/FileBufferingWriteStreamTests.cs b/src/Http/WebUtilities/test/FileBufferingWriteStreamTests.cs
index 14f0c081b5..987c6388e5 100644
--- a/src/Http/WebUtilities/test/FileBufferingWriteStreamTests.cs
+++ b/src/Http/WebUtilities/test/FileBufferingWriteStreamTests.cs
@@ -31,6 +31,8 @@ namespace Microsoft.AspNetCore.WebUtilities
bufferingStream.Write(input, 0, input.Length);
// Assert
+ Assert.Equal(input.Length, bufferingStream.Length);
+
// We should have written content to memory
var pagedByteBuffer = bufferingStream.PagedByteBuffer;
Assert.Equal(input, ReadBufferedContent(pagedByteBuffer));
@@ -53,6 +55,8 @@ namespace Microsoft.AspNetCore.WebUtilities
var pageBuffer = bufferingStream.PagedByteBuffer;
var fileStream = bufferingStream.FileStream;
+ Assert.Equal(input.Length, bufferingStream.Length);
+
// File should have been created.
Assert.Null(fileStream);
@@ -238,6 +242,8 @@ namespace Microsoft.AspNetCore.WebUtilities
Assert.NotNull(fileStream);
var fileBytes = ReadFileContent(fileStream);
+ Assert.Equal(input.Length, bufferingStream.Length);
+
Assert.Equal(new byte[] { 1, 2, 3, 4, 5, }, fileBytes);
Assert.Equal(new byte[] { 6, 7 }, ReadBufferedContent(pageBuffer));
}
@@ -344,6 +350,7 @@ namespace Microsoft.AspNetCore.WebUtilities
// Assert
Assert.Equal(input, memoryStream.ToArray());
+ Assert.Equal(0, bufferingStream.Length);
}
[Fact]
@@ -360,6 +367,7 @@ namespace Microsoft.AspNetCore.WebUtilities
// Assert
Assert.Equal(input, memoryStream.ToArray());
+ Assert.Equal(0, bufferingStream.Length);
}
public void Dispose()
diff --git a/src/Mvc/Mvc.Formatters.Xml/src/XmlDataContractSerializerOutputFormatter.cs b/src/Mvc/Mvc.Formatters.Xml/src/XmlDataContractSerializerOutputFormatter.cs
index b2a7d486b9..8f66c2842a 100644
--- a/src/Mvc/Mvc.Formatters.Xml/src/XmlDataContractSerializerOutputFormatter.cs
+++ b/src/Mvc/Mvc.Formatters.Xml/src/XmlDataContractSerializerOutputFormatter.cs
@@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
public XmlWriterSettings WriterSettings { get; }
///
- /// Gets or sets the used to configure the
+ /// Gets or sets the used to configure the
/// .
///
public DataContractSerializerSettings SerializerSettings
@@ -284,6 +284,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
if (fileBufferingWriteStream != null)
{
+ response.ContentLength = fileBufferingWriteStream.Length;
await fileBufferingWriteStream.DrainBufferAsync(response.Body);
}
}
diff --git a/src/Mvc/Mvc.Formatters.Xml/src/XmlSerializerOutputFormatter.cs b/src/Mvc/Mvc.Formatters.Xml/src/XmlSerializerOutputFormatter.cs
index fc845f7564..e6243fcb45 100644
--- a/src/Mvc/Mvc.Formatters.Xml/src/XmlSerializerOutputFormatter.cs
+++ b/src/Mvc/Mvc.Formatters.Xml/src/XmlSerializerOutputFormatter.cs
@@ -260,6 +260,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
if (fileBufferingWriteStream != null)
{
+ response.ContentLength = fileBufferingWriteStream.Length;
await fileBufferingWriteStream.DrainBufferAsync(response.Body);
}
}
diff --git a/src/Mvc/Mvc.NewtonsoftJson/src/NewtonsoftJsonOutputFormatter.cs b/src/Mvc/Mvc.NewtonsoftJson/src/NewtonsoftJsonOutputFormatter.cs
index 80a1fc3b7d..b6889c1c2d 100644
--- a/src/Mvc/Mvc.NewtonsoftJson/src/NewtonsoftJsonOutputFormatter.cs
+++ b/src/Mvc/Mvc.NewtonsoftJson/src/NewtonsoftJsonOutputFormatter.cs
@@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
///
/// Called during serialization to create the .The formatter context
- /// that is passed gives an ability to create serializer specific to the context.
+ /// that is passed gives an ability to create serializer specific to the context.
///
/// The used during serialization and deserialization.
protected virtual JsonSerializer CreateJsonSerializer()
@@ -109,7 +109,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
///
/// Called during serialization to create the .The formatter context
- /// that is passed gives an ability to create serializer specific to the context.
+ /// that is passed gives an ability to create serializer specific to the context.
///
/// A context object for .
/// The used during serialization and deserialization.
@@ -154,6 +154,7 @@ namespace Microsoft.AspNetCore.Mvc.Formatters
if (fileBufferingWriteStream != null)
{
+ response.ContentLength = fileBufferingWriteStream.Length;
await fileBufferingWriteStream.DrainBufferAsync(response.Body);
}
}
diff --git a/src/Mvc/test/Mvc.FunctionalTests/NewtonsoftJsonOutputFormatterTest.cs b/src/Mvc/test/Mvc.FunctionalTests/NewtonsoftJsonOutputFormatterTest.cs
index 58e77ca408..47696e446f 100644
--- a/src/Mvc/test/Mvc.FunctionalTests/NewtonsoftJsonOutputFormatterTest.cs
+++ b/src/Mvc/test/Mvc.FunctionalTests/NewtonsoftJsonOutputFormatterTest.cs
@@ -4,6 +4,7 @@
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.NewtonsoftJson;
+using FormatterWebSite.Controllers;
using Newtonsoft.Json;
using Xunit;
@@ -41,5 +42,16 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
var actualBody = await response.Content.ReadAsStringAsync();
Assert.Equal(expectedBody, actualBody);
}
+
+ [Fact]
+ public async Task JsonOutputFormatter_SetsContentLength()
+ {
+ // Act
+ var response = await Client.GetAsync($"/JsonOutputFormatter/{nameof(JsonOutputFormatterController.SimpleModelResult)}");
+
+ // Assert
+ await response.AssertStatusCodeAsync(HttpStatusCode.OK);
+ Assert.Equal(50, response.Content.Headers.ContentLength);
+ }
}
}
diff --git a/src/Mvc/test/Mvc.FunctionalTests/XmlOutputFormatterTests.cs b/src/Mvc/test/Mvc.FunctionalTests/XmlOutputFormatterTests.cs
index 35e406ac6a..f453e84741 100644
--- a/src/Mvc/test/Mvc.FunctionalTests/XmlOutputFormatterTests.cs
+++ b/src/Mvc/test/Mvc.FunctionalTests/XmlOutputFormatterTests.cs
@@ -41,6 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
"xmlns=\"http://schemas.datacontract.org/2004/07/FormatterWebSite\">" +
"10",
await response.Content.ReadAsStringAsync());
+ Assert.Equal(167, response.Content.Headers.ContentLength);
}
[Fact]
@@ -61,6 +62,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
"10",
await response.Content.ReadAsStringAsync());
+ Assert.Equal(149, response.Content.Headers.ContentLength);
}
[ConditionalFact]