Fix #3111 - Don't trounce content-type in VCR

This change makes ViewComponentResult respect an existing Content-Type
setting on the HttpResponse. Code is very similar to the code in
ViewExector, and includes the same quirks.
This commit is contained in:
Ryan Nowak 2015-09-21 15:23:35 -07:00
parent a318c4599a
commit b544aabfdb
3 changed files with 78 additions and 5 deletions

View File

@ -80,22 +80,32 @@ namespace Microsoft.AspNet.Mvc
viewData = new ViewDataDictionary(modelMetadataProvider, context.ModelState); viewData = new ViewDataDictionary(modelMetadataProvider, context.ModelState);
} }
var contentType = ContentType ?? ViewExecutor.DefaultContentType; var contentType = ContentType;
if (contentType.Encoding == null) if (contentType != null && 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;
} }
// Priority list for setting content-type/encoding:
// 1. this.ContentType (set by the user on the result)
// 2. response.ContentType (likely set by the user in controller code)
// 3. ViewExecutor.DefaultContentType (sensible default)
//
//
response.ContentType =
contentType?.ToString() ??
response.ContentType ??
ViewExecutor.DefaultContentType.ToString();
if (StatusCode != null) if (StatusCode != null)
{ {
response.StatusCode = StatusCode.Value; response.StatusCode = StatusCode.Value;
} }
response.ContentType = contentType.ToString(); var encoding = contentType?.Encoding ?? ViewExecutor.DefaultContentType?.Encoding;
using (var writer = new HttpResponseStreamWriter(response.Body, encoding))
using (var writer = new HttpResponseStreamWriter(response.Body, contentType.Encoding))
{ {
var viewContext = new ViewContext( var viewContext = new ViewContext(
context, context,

View File

@ -45,6 +45,10 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
contentType.Encoding = Encoding.UTF8; contentType.Encoding = Encoding.UTF8;
} }
// Priority list for setting content-type:
// 1. passed in contentType (likely set by the user on the result)
// 2. response.ContentType (likely set by the user in controller code)
// 3. ViewExecutor.DefaultContentType (sensible default)
response.ContentType = contentType?.ToString() ?? response.ContentType ?? DefaultContentType.ToString(); response.ContentType = contentType?.ToString() ?? response.ContentType ?? DefaultContentType.ToString();
using (var writer = new HttpResponseStreamWriter(response.Body, contentType?.Encoding ?? DefaultContentType.Encoding)) using (var writer = new HttpResponseStreamWriter(response.Body, contentType?.Encoding ?? DefaultContentType.Encoding))

View File

@ -309,6 +309,65 @@ namespace Microsoft.AspNet.Mvc
Assert.Equal(contentTypeBeforeViewResultExecution, contentTypeAfterViewResultExecution); Assert.Equal(contentTypeBeforeViewResultExecution, contentTypeAfterViewResultExecution);
} }
[Fact]
public async Task ViewComponentResult_SetsContentTypeHeader_OverrideResponseContentType()
{
// Arrange
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
Type = typeof(TextViewComponent),
};
var actionContext = CreateActionContext(descriptor);
var expectedContentType = "text/html; charset=utf-8";
actionContext.HttpContext.Response.ContentType = "application/x-will-be-overridden";
var viewComponentResult = new ViewComponentResult()
{
Arguments = new object[] { "World!" },
ViewComponentName = "Text",
ContentType = new MediaTypeHeaderValue("text/html") { Encoding = Encoding.UTF8 },
};
// Act
await viewComponentResult.ExecuteResultAsync(actionContext);
// Assert
Assert.Equal(expectedContentType, actionContext.HttpContext.Response.ContentType);
}
[Fact]
public async Task ViewComponentResult_NoContentTypeSet_PreservesResponseContentType()
{
// Arrange
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
Type = typeof(TextViewComponent),
};
var actionContext = CreateActionContext(descriptor);
var expectedContentType = "application/x-will-not-be-overridden";
actionContext.HttpContext.Response.ContentType = expectedContentType;
var viewComponentResult = new ViewComponentResult()
{
Arguments = new object[] { "World!" },
ViewComponentName = "Text",
};
// Act
await viewComponentResult.ExecuteResultAsync(actionContext);
// Assert
Assert.Equal(expectedContentType, actionContext.HttpContext.Response.ContentType);
}
private IServiceCollection CreateServices(params ViewComponentDescriptor[] descriptors) private IServiceCollection CreateServices(params ViewComponentDescriptor[] descriptors)
{ {
var services = new ServiceCollection(); var services = new ServiceCollection();