[Fixes #2947] Default ContentType is not set when user specified Response.ContentType exists
This commit is contained in:
parent
1596cd9422
commit
0beb39ec1c
|
|
@ -34,31 +34,18 @@ namespace Microsoft.AspNet.Mvc
|
||||||
public override async Task ExecuteResultAsync([NotNull] ActionContext context)
|
public override async Task ExecuteResultAsync([NotNull] ActionContext context)
|
||||||
{
|
{
|
||||||
var response = context.HttpContext.Response;
|
var response = context.HttpContext.Response;
|
||||||
|
|
||||||
var contentTypeHeader = ContentType;
|
var contentTypeHeader = ContentType;
|
||||||
Encoding encoding;
|
|
||||||
if (contentTypeHeader == null)
|
|
||||||
{
|
|
||||||
contentTypeHeader = DefaultContentType;
|
|
||||||
encoding = Encoding.UTF8;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (contentTypeHeader.Encoding == null)
|
|
||||||
{
|
|
||||||
// Do not modify the user supplied content type, so copy it instead
|
|
||||||
contentTypeHeader = contentTypeHeader.Copy();
|
|
||||||
contentTypeHeader.Encoding = Encoding.UTF8;
|
|
||||||
|
|
||||||
encoding = Encoding.UTF8;
|
if (contentTypeHeader != null && contentTypeHeader.Encoding == null)
|
||||||
}
|
{
|
||||||
else
|
// Do not modify the user supplied content type, so copy it instead
|
||||||
{
|
contentTypeHeader = contentTypeHeader.Copy();
|
||||||
encoding = contentTypeHeader.Encoding;
|
contentTypeHeader.Encoding = Encoding.UTF8;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response.ContentType = contentTypeHeader.ToString();
|
response.ContentType = contentTypeHeader?.ToString()
|
||||||
|
?? response.ContentType
|
||||||
|
?? DefaultContentType.ToString();
|
||||||
|
|
||||||
if (StatusCode != null)
|
if (StatusCode != null)
|
||||||
{
|
{
|
||||||
|
|
@ -67,7 +54,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
if (Content != null)
|
if (Content != null)
|
||||||
{
|
{
|
||||||
await response.WriteAsync(Content, encoding);
|
await response.WriteAsync(Content, contentTypeHeader?.Encoding ?? DefaultContentType.Encoding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,17 +36,16 @@ namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
var response = actionContext.HttpContext.Response;
|
var response = actionContext.HttpContext.Response;
|
||||||
|
|
||||||
contentType = contentType ?? DefaultContentType;
|
if (contentType != null && contentType.Encoding == null)
|
||||||
if (contentType.Encoding == null)
|
|
||||||
{
|
{
|
||||||
// Do not modify the user supplied content type, so copy it instead
|
// Do not modify the user supplied content type, so copy it instead
|
||||||
contentType = contentType.Copy();
|
contentType = contentType.Copy();
|
||||||
contentType.Encoding = Encoding.UTF8;
|
contentType.Encoding = Encoding.UTF8;
|
||||||
}
|
}
|
||||||
|
|
||||||
response.ContentType = contentType.ToString();
|
response.ContentType = contentType?.ToString() ?? response.ContentType ?? DefaultContentType.ToString();
|
||||||
|
|
||||||
using (var writer = new HttpResponseStreamWriter(response.Body, contentType.Encoding))
|
using (var writer = new HttpResponseStreamWriter(response.Body, contentType?.Encoding ?? DefaultContentType.Encoding))
|
||||||
{
|
{
|
||||||
var viewContext = new ViewContext(
|
var viewContext = new ViewContext(
|
||||||
actionContext,
|
actionContext,
|
||||||
|
|
|
||||||
|
|
@ -78,36 +78,68 @@ namespace Microsoft.AspNet.Mvc
|
||||||
Assert.Equal("text/plain; charset=utf-7", httpContext.Response.ContentType);
|
Assert.Equal("text/plain; charset=utf-7", httpContext.Response.ContentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TheoryData<MediaTypeHeaderValue, string, string, byte[]> ContentResultContentTypeData
|
public static TheoryData<MediaTypeHeaderValue, string, string, string, byte[]> ContentResultContentTypeData
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new TheoryData<MediaTypeHeaderValue, string, string, byte[]>
|
return new TheoryData<MediaTypeHeaderValue, string, string, string, byte[]>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
null,
|
null,
|
||||||
"κόσμε",
|
"κόσμε",
|
||||||
|
null,
|
||||||
"text/plain; charset=utf-8",
|
"text/plain; charset=utf-8",
|
||||||
new byte[] { 206, 186, 225, 189, 185, 207, 131, 206, 188, 206, 181 } //utf-8 without BOM
|
new byte[] { 206, 186, 225, 189, 185, 207, 131, 206, 188, 206, 181 } //utf-8 without BOM
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
new MediaTypeHeaderValue("text/foo"),
|
new MediaTypeHeaderValue("text/foo"),
|
||||||
"κόσμε",
|
"κόσμε",
|
||||||
|
null,
|
||||||
"text/foo; charset=utf-8",
|
"text/foo; charset=utf-8",
|
||||||
new byte[] { 206, 186, 225, 189, 185, 207, 131, 206, 188, 206, 181 } //utf-8 without BOM
|
new byte[] { 206, 186, 225, 189, 185, 207, 131, 206, 188, 206, 181 } //utf-8 without BOM
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
MediaTypeHeaderValue.Parse("text/foo;p1=p1-value"),
|
MediaTypeHeaderValue.Parse("text/foo;p1=p1-value"),
|
||||||
"κόσμε",
|
"κόσμε",
|
||||||
|
null,
|
||||||
"text/foo; p1=p1-value; charset=utf-8",
|
"text/foo; p1=p1-value; charset=utf-8",
|
||||||
new byte[] { 206, 186, 225, 189, 185, 207, 131, 206, 188, 206, 181 } //utf-8 without BOM
|
new byte[] { 206, 186, 225, 189, 185, 207, 131, 206, 188, 206, 181 } //utf-8 without BOM
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
new MediaTypeHeaderValue("text/foo") { Encoding = Encoding.ASCII },
|
new MediaTypeHeaderValue("text/foo") { Encoding = Encoding.ASCII },
|
||||||
"abcd",
|
"abcd",
|
||||||
|
null,
|
||||||
"text/foo; charset=us-ascii",
|
"text/foo; charset=us-ascii",
|
||||||
new byte[] { 97, 98, 99, 100 }
|
new byte[] { 97, 98, 99, 100 }
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
null,
|
||||||
|
"abcd",
|
||||||
|
"text/bar",
|
||||||
|
"text/bar",
|
||||||
|
new byte[] { 97, 98, 99, 100 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
null,
|
||||||
|
"abcd",
|
||||||
|
"application/xml; charset=us-ascii",
|
||||||
|
"application/xml; charset=us-ascii",
|
||||||
|
new byte[] { 97, 98, 99, 100 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
null,
|
||||||
|
"abcd",
|
||||||
|
"Invalid content type",
|
||||||
|
"Invalid content type",
|
||||||
|
new byte[] { 97, 98, 99, 100 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new MediaTypeHeaderValue("text/foo") { Charset = "us-ascii" },
|
||||||
|
"abcd",
|
||||||
|
"text/bar",
|
||||||
|
"text/foo; charset=us-ascii",
|
||||||
|
new byte[] { 97, 98, 99, 100 }
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -117,6 +149,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
public async Task ContentResult_ExecuteResultAsync_SetContentTypeAndEncoding_OnResponse(
|
public async Task ContentResult_ExecuteResultAsync_SetContentTypeAndEncoding_OnResponse(
|
||||||
MediaTypeHeaderValue contentType,
|
MediaTypeHeaderValue contentType,
|
||||||
string content,
|
string content,
|
||||||
|
string responseContentType,
|
||||||
string expectedContentType,
|
string expectedContentType,
|
||||||
byte[] expectedContentData)
|
byte[] expectedContentData)
|
||||||
{
|
{
|
||||||
|
|
@ -129,6 +162,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
var httpContext = GetHttpContext();
|
var httpContext = GetHttpContext();
|
||||||
var memoryStream = new MemoryStream();
|
var memoryStream = new MemoryStream();
|
||||||
httpContext.Response.Body = memoryStream;
|
httpContext.Response.Body = memoryStream;
|
||||||
|
httpContext.Response.ContentType = responseContentType;
|
||||||
var actionContext = GetActionContext(httpContext);
|
var actionContext = GetActionContext(httpContext);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,12 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http.Internal;
|
using Microsoft.AspNet.Http.Internal;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
using Microsoft.AspNet.Routing;
|
using Microsoft.AspNet.Routing;
|
||||||
using Microsoft.AspNet.Testing;
|
|
||||||
using Microsoft.Net.Http.Headers;
|
using Microsoft.Net.Http.Headers;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -18,32 +16,60 @@ namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
public class ViewExecutorTest
|
public class ViewExecutorTest
|
||||||
{
|
{
|
||||||
public static TheoryData<MediaTypeHeaderValue, string, byte[]> ViewExecutorSetsContentTypeAndEncodingData
|
public static TheoryData<MediaTypeHeaderValue, string, string, byte[]> ViewExecutorSetsContentTypeAndEncodingData
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new TheoryData<MediaTypeHeaderValue, string, byte[]>
|
return new TheoryData<MediaTypeHeaderValue, string, string, byte[]>
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
null,
|
||||||
null,
|
null,
|
||||||
"text/html; charset=utf-8",
|
"text/html; charset=utf-8",
|
||||||
new byte[] { 97, 98, 99, 100 }
|
new byte[] { 97, 98, 99, 100 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
new MediaTypeHeaderValue("text/foo"),
|
new MediaTypeHeaderValue("text/foo"),
|
||||||
|
null,
|
||||||
"text/foo; charset=utf-8",
|
"text/foo; charset=utf-8",
|
||||||
new byte[] { 97, 98, 99, 100 }
|
new byte[] { 97, 98, 99, 100 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
MediaTypeHeaderValue.Parse("text/foo; p1=p1-value"),
|
MediaTypeHeaderValue.Parse("text/foo; p1=p1-value"),
|
||||||
|
null,
|
||||||
"text/foo; p1=p1-value; charset=utf-8",
|
"text/foo; p1=p1-value; charset=utf-8",
|
||||||
new byte[] { 97, 98, 99, 100 }
|
new byte[] { 97, 98, 99, 100 }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
new MediaTypeHeaderValue("text/foo") { Charset = "us-ascii" },
|
new MediaTypeHeaderValue("text/foo") { Charset = "us-ascii" },
|
||||||
|
null,
|
||||||
"text/foo; charset=us-ascii",
|
"text/foo; charset=us-ascii",
|
||||||
new byte[] { 97, 98, 99, 100 }
|
new byte[] { 97, 98, 99, 100 }
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
null,
|
||||||
|
"text/bar",
|
||||||
|
"text/bar",
|
||||||
|
new byte[] { 97, 98, 99, 100 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
null,
|
||||||
|
"application/xml; charset=us-ascii",
|
||||||
|
"application/xml; charset=us-ascii",
|
||||||
|
new byte[] { 97, 98, 99, 100 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
null,
|
||||||
|
"Invalid content type",
|
||||||
|
"Invalid content type",
|
||||||
|
new byte[] { 97, 98, 99, 100 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new MediaTypeHeaderValue("text/foo") { Charset = "us-ascii" },
|
||||||
|
"text/bar",
|
||||||
|
"text/foo; charset=us-ascii",
|
||||||
|
new byte[] { 97, 98, 99, 100 }
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -52,6 +78,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
[MemberData(nameof(ViewExecutorSetsContentTypeAndEncodingData))]
|
[MemberData(nameof(ViewExecutorSetsContentTypeAndEncodingData))]
|
||||||
public async Task ExecuteAsync_SetsContentTypeAndEncoding(
|
public async Task ExecuteAsync_SetsContentTypeAndEncoding(
|
||||||
MediaTypeHeaderValue contentType,
|
MediaTypeHeaderValue contentType,
|
||||||
|
string responseContentType,
|
||||||
string expectedContentType,
|
string expectedContentType,
|
||||||
byte[] expectedContentData)
|
byte[] expectedContentData)
|
||||||
{
|
{
|
||||||
|
|
@ -68,6 +95,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
var context = new DefaultHttpContext();
|
var context = new DefaultHttpContext();
|
||||||
var memoryStream = new MemoryStream();
|
var memoryStream = new MemoryStream();
|
||||||
context.Response.Body = memoryStream;
|
context.Response.Body = memoryStream;
|
||||||
|
context.Response.ContentType = responseContentType;
|
||||||
|
|
||||||
var actionContext = new ActionContext(context,
|
var actionContext = new ActionContext(context,
|
||||||
new RouteData(),
|
new RouteData(),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue