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:
parent
a318c4599a
commit
b544aabfdb
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue