Add explicit content types to 'no formatter' logging (#11213)
* Add explicit content types to 'no formatter' logging * Remove dead code
This commit is contained in:
parent
0274aceaee
commit
7003fb53d5
|
|
@ -147,14 +147,11 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedFormatter == null)
|
if (selectedFormatter != null)
|
||||||
{
|
{
|
||||||
// No formatter supports this.
|
_logger.FormatterSelected(selectedFormatter, context);
|
||||||
_logger.NoFormatter(context);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.FormatterSelected(selectedFormatter, context);
|
|
||||||
return selectedFormatter;
|
return selectedFormatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ namespace Microsoft.AspNetCore.Mvc.Infrastructure
|
||||||
if (selectedFormatter == null)
|
if (selectedFormatter == null)
|
||||||
{
|
{
|
||||||
// No formatter supports this.
|
// No formatter supports this.
|
||||||
Logger.NoFormatter(formatterContext);
|
Logger.NoFormatter(formatterContext, result.ContentTypes);
|
||||||
|
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status406NotAcceptable;
|
context.HttpContext.Response.StatusCode = StatusCodes.Status406NotAcceptable;
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
|
@ -28,8 +27,6 @@ namespace Microsoft.AspNetCore.Mvc
|
||||||
public const string ActionFilter = "Action Filter";
|
public const string ActionFilter = "Action Filter";
|
||||||
private static readonly string[] _noFilters = new[] { "None" };
|
private static readonly string[] _noFilters = new[] { "None" };
|
||||||
|
|
||||||
private static readonly double TimestampToTicks = TimeSpan.TicksPerSecond / (double)Stopwatch.Frequency;
|
|
||||||
|
|
||||||
private static readonly Action<ILogger, string, string, Exception> _actionExecuting;
|
private static readonly Action<ILogger, string, string, Exception> _actionExecuting;
|
||||||
private static readonly Action<ILogger, string, MethodInfo, string, string, Exception> _controllerActionExecuting;
|
private static readonly Action<ILogger, string, MethodInfo, string, string, Exception> _controllerActionExecuting;
|
||||||
private static readonly Action<ILogger, string, double, Exception> _actionExecuted;
|
private static readonly Action<ILogger, string, double, Exception> _actionExecuted;
|
||||||
|
|
@ -73,7 +70,7 @@ namespace Microsoft.AspNetCore.Mvc
|
||||||
private static readonly Action<ILogger, string, Exception> _localRedirectResultExecuting;
|
private static readonly Action<ILogger, string, Exception> _localRedirectResultExecuting;
|
||||||
|
|
||||||
private static readonly Action<ILogger, string, Exception> _objectResultExecuting;
|
private static readonly Action<ILogger, string, Exception> _objectResultExecuting;
|
||||||
private static readonly Action<ILogger, string, Exception> _noFormatter;
|
private static readonly Action<ILogger, IEnumerable<string>, Exception> _noFormatter;
|
||||||
private static readonly Action<ILogger, IOutputFormatter, string, Exception> _formatterSelected;
|
private static readonly Action<ILogger, IOutputFormatter, string, Exception> _formatterSelected;
|
||||||
private static readonly Action<ILogger, string, Exception> _skippedContentNegotiation;
|
private static readonly Action<ILogger, string, Exception> _skippedContentNegotiation;
|
||||||
private static readonly Action<ILogger, Exception> _noAcceptForNegotiation;
|
private static readonly Action<ILogger, Exception> _noAcceptForNegotiation;
|
||||||
|
|
@ -300,10 +297,10 @@ namespace Microsoft.AspNetCore.Mvc
|
||||||
new EventId(1, "LocalRedirectResultExecuting"),
|
new EventId(1, "LocalRedirectResultExecuting"),
|
||||||
"Executing LocalRedirectResult, redirecting to {Destination}.");
|
"Executing LocalRedirectResult, redirecting to {Destination}.");
|
||||||
|
|
||||||
_noFormatter = LoggerMessage.Define<string>(
|
_noFormatter = LoggerMessage.Define<IEnumerable<string>>(
|
||||||
LogLevel.Warning,
|
LogLevel.Warning,
|
||||||
new EventId(1, "NoFormatter"),
|
new EventId(1, "NoFormatter"),
|
||||||
"No output formatter was found for content type '{ContentType}' to write the response.");
|
"No output formatter was found for content types '{ContentTypes}' to write the response.");
|
||||||
|
|
||||||
_objectResultExecuting = LoggerMessage.Define<string>(
|
_objectResultExecuting = LoggerMessage.Define<string>(
|
||||||
LogLevel.Information,
|
LogLevel.Information,
|
||||||
|
|
@ -1017,11 +1014,19 @@ namespace Microsoft.AspNetCore.Mvc
|
||||||
|
|
||||||
public static void NoFormatter(
|
public static void NoFormatter(
|
||||||
this ILogger logger,
|
this ILogger logger,
|
||||||
OutputFormatterCanWriteContext formatterContext)
|
OutputFormatterCanWriteContext context,
|
||||||
|
MediaTypeCollection contentTypes)
|
||||||
{
|
{
|
||||||
if (logger.IsEnabled(LogLevel.Warning))
|
if (logger.IsEnabled(LogLevel.Warning))
|
||||||
{
|
{
|
||||||
_noFormatter(logger, Convert.ToString(formatterContext.ContentType), null);
|
var considered = new List<string>(contentTypes);
|
||||||
|
|
||||||
|
if (context.ContentType.HasValue)
|
||||||
|
{
|
||||||
|
considered.Add(Convert.ToString(context.ContentType));
|
||||||
|
}
|
||||||
|
|
||||||
|
_noFormatter(logger, considered, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// 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 Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Formatters;
|
||||||
using Microsoft.Extensions.Logging.Testing;
|
using Microsoft.Extensions.Logging.Testing;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -282,6 +284,37 @@ namespace Microsoft.AspNetCore.Mvc
|
||||||
write.State.ToString());
|
write.State.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void NoFormatter_LogsListOfContentTypes()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var testSink = new TestSink();
|
||||||
|
var loggerFactory = new TestLoggerFactory(testSink, enabled: true);
|
||||||
|
var logger = loggerFactory.CreateLogger("test");
|
||||||
|
|
||||||
|
var mediaTypes = new MediaTypeCollection
|
||||||
|
{
|
||||||
|
"application/problem+json",
|
||||||
|
"application/problem+xml",
|
||||||
|
};
|
||||||
|
|
||||||
|
var httpContext = Mock.Of<HttpContext>();
|
||||||
|
var context = new Mock<OutputFormatterCanWriteContext>(httpContext);
|
||||||
|
|
||||||
|
context.SetupGet(x => x.ContentType).Returns("application/json");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
logger.NoFormatter(context.Object, mediaTypes);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var write = Assert.Single(testSink.Writes);
|
||||||
|
Assert.Equal(
|
||||||
|
"No output formatter was found for content types " +
|
||||||
|
"'application/problem+json, application/problem+xml, application/json'" +
|
||||||
|
" to write the response.",
|
||||||
|
write.State.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
public interface IOrderedAuthorizeFilter : IAuthorizationFilter, IAsyncAuthorizationFilter, IOrderedFilter { }
|
public interface IOrderedAuthorizeFilter : IAuthorizationFilter, IAsyncAuthorizationFilter, IOrderedFilter { }
|
||||||
|
|
||||||
public interface IOrderedResourceFilter : IResourceFilter, IAsyncResourceFilter, IOrderedFilter { }
|
public interface IOrderedResourceFilter : IResourceFilter, IAsyncResourceFilter, IOrderedFilter { }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue