diff --git a/src/Microsoft.AspNet.Mvc.Core/ChallengeResult.cs b/src/Microsoft.AspNet.Mvc.Core/ChallengeResult.cs index 1057916ac8..bd75945fdb 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ChallengeResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ChallengeResult.cs @@ -5,6 +5,9 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNet.Http.Authentication; +using Microsoft.AspNet.Mvc.Logging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; namespace Microsoft.AspNet.Mvc { @@ -52,18 +55,23 @@ namespace Microsoft.AspNet.Mvc throw new ArgumentNullException(nameof(context)); } - var auth = context.HttpContext.Authentication; + var loggerFactory = context.HttpContext.RequestServices.GetRequiredService(); + var logger = loggerFactory.CreateLogger(); + + var authentication = context.HttpContext.Authentication; if (AuthenticationSchemes.Count > 0) { foreach (var scheme in AuthenticationSchemes) { - await auth.ChallengeAsync(scheme, Properties); + await authentication.ChallengeAsync(scheme, Properties); } } else { - await auth.ChallengeAsync(Properties); + await authentication.ChallengeAsync(Properties); } + + logger.ChallengeResultExecuting(AuthenticationSchemes); } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ContentResult.cs b/src/Microsoft.AspNet.Mvc.Core/ContentResult.cs index 224a3c211c..d2bbf4e023 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ContentResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ContentResult.cs @@ -7,6 +7,9 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Features; using Microsoft.AspNet.Mvc.Internal; +using Microsoft.AspNet.Mvc.Logging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc @@ -40,6 +43,9 @@ namespace Microsoft.AspNet.Mvc throw new ArgumentNullException(nameof(context)); } + var loggerFactory = context.HttpContext.RequestServices.GetRequiredService(); + var logger = loggerFactory.CreateLogger(); + var response = context.HttpContext.Response; var contentTypeHeader = ContentType; @@ -59,6 +65,8 @@ namespace Microsoft.AspNet.Mvc response.StatusCode = StatusCode.Value; } + logger.ContentResultExecuting(contentTypeHeader); + if (Content != null) { var bufferingFeature = response.HttpContext.Features.Get(); diff --git a/src/Microsoft.AspNet.Mvc.Core/Controllers/ControllerActionExecutor.cs b/src/Microsoft.AspNet.Mvc.Core/Controllers/ControllerActionExecutor.cs index 7a9d897da4..25465b1fbf 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Controllers/ControllerActionExecutor.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Controllers/ControllerActionExecutor.cs @@ -103,7 +103,7 @@ namespace Microsoft.AspNet.Mvc.Controllers } } - private static object[] PrepareArguments( + public static object[] PrepareArguments( IDictionary actionParameters, ParameterInfo[] declaredParameterInfos) { diff --git a/src/Microsoft.AspNet.Mvc.Core/Controllers/ControllerActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/Controllers/ControllerActionInvoker.cs index 8eac814517..a423dddeac 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Controllers/ControllerActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Controllers/ControllerActionInvoker.cs @@ -10,6 +10,7 @@ using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.Filters; using Microsoft.AspNet.Mvc.Formatters; using Microsoft.AspNet.Mvc.Infrastructure; +using Microsoft.AspNet.Mvc.Logging; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.Extensions.Internal; @@ -144,14 +145,23 @@ namespace Microsoft.AspNet.Mvc.Controllers protected override async Task InvokeActionAsync(ActionExecutingContext actionExecutingContext) { var actionMethodInfo = _descriptor.MethodInfo; + var arguments = ControllerActionExecutor.PrepareArguments( + actionExecutingContext.ActionArguments, + actionMethodInfo.GetParameters()); + + Logger.ActionMethodExecuting(actionExecutingContext, arguments); + var actionReturnValue = await ControllerActionExecutor.ExecuteAsync( actionMethodInfo, actionExecutingContext.Controller, - actionExecutingContext.ActionArguments); + arguments); var actionResult = CreateActionResult( actionMethodInfo.ReturnType, actionReturnValue); + + Logger.ActionMethodExecuted(actionExecutingContext, actionResult); + return actionResult; } diff --git a/src/Microsoft.AspNet.Mvc.Core/Controllers/FilterActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/Controllers/FilterActionInvoker.cs index 8d94381193..b342a48009 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Controllers/FilterActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Controllers/FilterActionInvoker.cs @@ -29,7 +29,6 @@ namespace Microsoft.AspNet.Mvc.Controllers private readonly IReadOnlyList _modelValidatorProviders; private readonly IReadOnlyList _valueProviderFactories; private readonly IActionBindingContextAccessor _actionBindingContextAccessor; - private readonly ILogger _logger; private readonly DiagnosticSource _diagnosticSource; private readonly int _maxModelValidationErrors; @@ -132,7 +131,7 @@ namespace Microsoft.AspNet.Mvc.Controllers _modelValidatorProviders = modelValidatorProviders; _valueProviderFactories = valueProviderFactories; _actionBindingContextAccessor = actionBindingContextAccessor; - _logger = logger; + Logger = logger; _diagnosticSource = diagnosticSource; _maxModelValidationErrors = maxModelValidationErrors; } @@ -153,6 +152,8 @@ namespace Microsoft.AspNet.Mvc.Controllers protected object Instance { get; private set; } + protected ILogger Logger { get; } + /// /// Called to create an instance of an object which will act as the reciever of the action invocation. /// @@ -296,7 +297,7 @@ namespace Microsoft.AspNet.Mvc.Controllers } else { - _logger.LogWarning(AuthorizationFailureLogMessage, current.FilterAsync.GetType().FullName); + Logger.LogWarning(AuthorizationFailureLogMessage, current.FilterAsync.GetType().FullName); } } else if (current.Filter != null) @@ -310,7 +311,7 @@ namespace Microsoft.AspNet.Mvc.Controllers } else { - _logger.LogWarning(AuthorizationFailureLogMessage, current.Filter.GetType().FullName); + Logger.LogWarning(AuthorizationFailureLogMessage, current.Filter.GetType().FullName); } } else @@ -366,7 +367,7 @@ namespace Microsoft.AspNet.Mvc.Controllers // If we get here then the filter didn't call 'next' indicating a short circuit if (_resourceExecutingContext.Result != null) { - _logger.LogVerbose( + Logger.LogVerbose( ResourceFilterShortCircuitLogMessage, item.FilterAsync.GetType().FullName); @@ -387,8 +388,7 @@ namespace Microsoft.AspNet.Mvc.Controllers if (_resourceExecutingContext.Result != null) { // Short-circuited by setting a result. - - _logger.LogVerbose(ResourceFilterShortCircuitLogMessage, item.Filter.GetType().FullName); + Logger.LogVerbose(ResourceFilterShortCircuitLogMessage, item.Filter.GetType().FullName); await InvokeResultAsync(_resourceExecutingContext.Result); @@ -506,7 +506,7 @@ namespace Microsoft.AspNet.Mvc.Controllers if (_exceptionContext.Exception == null) { - _logger.LogVerbose( + Logger.LogVerbose( ExceptionFilterShortCircuitLogMessage, current.FilterAsync.GetType().FullName); } @@ -527,7 +527,7 @@ namespace Microsoft.AspNet.Mvc.Controllers if (_exceptionContext.Exception == null) { - _logger.LogVerbose( + Logger.LogVerbose( ExceptionFilterShortCircuitLogMessage, current.Filter.GetType().FullName); } @@ -608,7 +608,7 @@ namespace Microsoft.AspNet.Mvc.Controllers { // If we get here then the filter didn't call 'next' indicating a short circuit - _logger.LogVerbose(ActionFilterShortCircuitLogMessage, item.FilterAsync.GetType().FullName); + Logger.LogVerbose(ActionFilterShortCircuitLogMessage, item.FilterAsync.GetType().FullName); _actionExecutedContext = new ActionExecutedContext( _actionExecutingContext, @@ -628,7 +628,7 @@ namespace Microsoft.AspNet.Mvc.Controllers { // Short-circuited by setting a result. - _logger.LogVerbose(ActionFilterShortCircuitLogMessage, item.Filter.GetType().FullName); + Logger.LogVerbose(ActionFilterShortCircuitLogMessage, item.Filter.GetType().FullName); _actionExecutedContext = new ActionExecutedContext( _actionExecutingContext, @@ -752,8 +752,7 @@ namespace Microsoft.AspNet.Mvc.Controllers if (_resultExecutedContext == null || _resultExecutingContext.Cancel == true) { // Short-circuited by not calling next || Short-circuited by setting Cancel == true - - _logger.LogVerbose(ResourceFilterShortCircuitLogMessage, item.FilterAsync.GetType().FullName); + Logger.LogVerbose(ResourceFilterShortCircuitLogMessage, item.FilterAsync.GetType().FullName); _resultExecutedContext = new ResultExecutedContext( _resultExecutingContext, @@ -772,8 +771,7 @@ namespace Microsoft.AspNet.Mvc.Controllers if (_resultExecutingContext.Cancel == true) { // Short-circuited by setting Cancel == true - - _logger.LogVerbose(ResourceFilterShortCircuitLogMessage, item.Filter.GetType().FullName); + Logger.LogVerbose(ResourceFilterShortCircuitLogMessage, item.Filter.GetType().FullName); _resultExecutedContext = new ResultExecutedContext( _resultExecutingContext, diff --git a/src/Microsoft.AspNet.Mvc.Core/FileResult.cs b/src/Microsoft.AspNet.Mvc.Core/FileResult.cs index 504cfcdd4f..d94ba49061 100644 --- a/src/Microsoft.AspNet.Mvc.Core/FileResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/FileResult.cs @@ -4,6 +4,9 @@ using System; using System.Threading.Tasks; using Microsoft.AspNet.Http; +using Microsoft.AspNet.Mvc.Logging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Microsoft.Net.Http.Headers; namespace Microsoft.AspNet.Mvc @@ -67,6 +70,9 @@ namespace Microsoft.AspNet.Mvc throw new ArgumentNullException(nameof(context)); } + var loggerFactory = context.HttpContext.RequestServices.GetRequiredService(); + var logger = loggerFactory?.CreateLogger(); + var response = context.HttpContext.Response; response.ContentType = ContentType.ToString(); @@ -77,11 +83,12 @@ namespace Microsoft.AspNet.Mvc // detached and stored in a separate file. If the receiving MUA writes // the entity to a file, the suggested filename should be used as a // basis for the actual filename, where possible. - var cd = new ContentDispositionHeaderValue("attachment"); - cd.SetHttpFileName(FileDownloadName); - context.HttpContext.Response.Headers[HeaderNames.ContentDisposition] = cd.ToString(); + var contentDisposition = new ContentDispositionHeaderValue("attachment"); + contentDisposition.SetHttpFileName(FileDownloadName); + context.HttpContext.Response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString(); } - + + logger.FileResultExecuting(FileDownloadName); return WriteFileAsync(response); } diff --git a/src/Microsoft.AspNet.Mvc.Core/HttpStatusCodeResult.cs b/src/Microsoft.AspNet.Mvc.Core/HttpStatusCodeResult.cs index 6e663a261f..c523ee9953 100644 --- a/src/Microsoft.AspNet.Mvc.Core/HttpStatusCodeResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/HttpStatusCodeResult.cs @@ -2,6 +2,9 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNet.Mvc.Logging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; namespace Microsoft.AspNet.Mvc { @@ -34,6 +37,11 @@ namespace Microsoft.AspNet.Mvc throw new ArgumentNullException(nameof(context)); } + var factory = context.HttpContext.RequestServices.GetRequiredService(); + var logger = factory.CreateLogger(); + + logger.HttpStatusCodeResultExecuting(StatusCode); + context.HttpContext.Response.StatusCode = StatusCode; } } diff --git a/src/Microsoft.AspNet.Mvc.Core/Infrastructure/ObjectResultExecutor.cs b/src/Microsoft.AspNet.Mvc.Core/Infrastructure/ObjectResultExecutor.cs index ff445e46fc..2b76db181e 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Infrastructure/ObjectResultExecutor.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Infrastructure/ObjectResultExecutor.cs @@ -9,6 +9,7 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.Formatters; using Microsoft.AspNet.Mvc.Internal; +using Microsoft.AspNet.Mvc.Logging; using Microsoft.Extensions.Logging; using Microsoft.Extensions.OptionsModel; using Microsoft.Net.Http.Headers; @@ -125,7 +126,9 @@ namespace Microsoft.AspNet.Mvc.Infrastructure "'{ContentType}' to write the response.", selectedFormatter.GetType().FullName, formatterContext.ContentType); - + + Logger.ObjectResultExecuting(context); + result.OnFormatting(context); return selectedFormatter.WriteAsync(formatterContext); } diff --git a/src/Microsoft.AspNet.Mvc.Core/Logging/ChallengeResultLoggerExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/Logging/ChallengeResultLoggerExtensions.cs new file mode 100644 index 0000000000..189b15e2b6 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Logging/ChallengeResultLoggerExtensions.cs @@ -0,0 +1,28 @@ +// 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. + +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNet.Mvc.Logging +{ + public static class ChallengeResultLoggerExtenstions + { + private static Action _challengeResultExecuting; + + static ChallengeResultLoggerExtenstions() + { + _challengeResultExecuting = LoggerMessage.Define( + LogLevel.Information, + 1, + "Executing ChallengeResult with authentication schemes ({Schemes})."); + } + + public static void ChallengeResultExecuting(this ILogger logger, IList schemes) + { + _challengeResultExecuting(logger, schemes.ToArray(), null); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/Logging/ContentResultLoggerExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/Logging/ContentResultLoggerExtensions.cs new file mode 100644 index 0000000000..3ca9bdc8db --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Logging/ContentResultLoggerExtensions.cs @@ -0,0 +1,27 @@ +// 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. + +using System; +using Microsoft.Extensions.Logging; +using Microsoft.Net.Http.Headers; + +namespace Microsoft.AspNet.Mvc.Logging +{ + public static class ContentResultLoggerExtensions + { + private static Action _contentResultExecuting; + + static ContentResultLoggerExtensions() + { + _contentResultExecuting = LoggerMessage.Define( + LogLevel.Information, + 1, + "Executing ContentResult with HTTP Response ContentType of {ContentType}"); + } + + public static void ContentResultExecuting(this ILogger logger, MediaTypeHeaderValue contentType) + { + _contentResultExecuting(logger, contentType?.MediaType, null); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/Logging/ControllerActionInvokerLoggerExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/Logging/ControllerActionInvokerLoggerExtensions.cs new file mode 100644 index 0000000000..f1a590c291 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Logging/ControllerActionInvokerLoggerExtensions.cs @@ -0,0 +1,61 @@ +// 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. + +using System; +using Microsoft.AspNet.Mvc.Filters; +using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNet.Mvc.Logging +{ + public static class ControllerActionInvokerLoggerExtensions + { + private static Action _actionMethodExecuting; + private static Action _actionMethodExecuted; + + static ControllerActionInvokerLoggerExtensions() + { + _actionMethodExecuting = LoggerMessage.Define( + LogLevel.Information, + 1, + "Executing action method {ActionName} with arguments ({Arguments}) - ModelState is {ValidationState}'"); + + _actionMethodExecuted = LoggerMessage.Define( + LogLevel.Information, + 2, + "Executed action method {ActionName}, returned result {ActionResult}.'"); + } + + public static void ActionMethodExecuting(this ILogger logger, ActionExecutingContext context, object[] arguments) + { + if (logger.IsEnabled(LogLevel.Information)) + { + var actionName = context.ActionDescriptor.DisplayName; + + string[] convertedArguments; + if (arguments == null) + { + convertedArguments = null; + } + else + { + convertedArguments = new string[arguments.Length]; + for (var i = 0; i < arguments.Length; i++) + { + convertedArguments[i] = Convert.ToString(arguments[i]); + } + } + + var validationState = context.ModelState.ValidationState; + + _actionMethodExecuting(logger, actionName, convertedArguments, validationState, null); + } + } + + public static void ActionMethodExecuted(this ILogger logger, ActionExecutingContext context, IActionResult result) + { + var actionName = context.ActionDescriptor.DisplayName; + _actionMethodExecuted(logger, actionName, Convert.ToString(result), null); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/Logging/FileResultLoggerExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/Logging/FileResultLoggerExtensions.cs new file mode 100644 index 0000000000..6032c0afc5 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Logging/FileResultLoggerExtensions.cs @@ -0,0 +1,26 @@ +// 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. + +using System; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNet.Mvc.Logging +{ + public static class FileResultLoggerExtensions + { + private static Action _fileResultExecuting; + + static FileResultLoggerExtensions() + { + _fileResultExecuting = LoggerMessage.Define( + LogLevel.Information, + 1, + "Executing FileResult, sending file as {FileDownloadName}"); + } + + public static void FileResultExecuting(this ILogger logger, string fileDownloadName) + { + _fileResultExecuting(logger, fileDownloadName, null); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/Logging/HttpStatusCodeResultLoggerExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/Logging/HttpStatusCodeResultLoggerExtensions.cs new file mode 100644 index 0000000000..ab8660ffba --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Logging/HttpStatusCodeResultLoggerExtensions.cs @@ -0,0 +1,26 @@ +// 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. + +using System; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNet.Mvc.Logging +{ + public static class HttpStatusCodeLoggerExtensions + { + private static Action _httpStatusCodeResultExecuting; + + static HttpStatusCodeLoggerExtensions() + { + _httpStatusCodeResultExecuting = LoggerMessage.Define( + LogLevel.Information, + 1, + "Executing HttpStatusCodeResult, setting HTTP status code {StatusCode}"); + } + + public static void HttpStatusCodeResultExecuting(this ILogger logger, int statusCode) + { + _httpStatusCodeResultExecuting(logger, statusCode, null); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/Logging/JsonResultLoggerExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/Logging/JsonResultLoggerExtensions.cs new file mode 100644 index 0000000000..d1c05988e5 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Logging/JsonResultLoggerExtensions.cs @@ -0,0 +1,26 @@ +// 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. + +using System; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNet.Mvc.Logging +{ + public static class JsonResultLoggerExtensions + { + private static Action _jsonResultExecuting; + + static JsonResultLoggerExtensions() + { + _jsonResultExecuting = LoggerMessage.Define( + LogLevel.Information, + 1, + "Executing JsonResult, writing value {Value}."); + } + + public static void JsonResultExecuting(this ILogger logger, object value) + { + _jsonResultExecuting(logger, Convert.ToString(value), null); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/Logging/ObjectResultExecutorLoggerExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/Logging/ObjectResultExecutorLoggerExtensions.cs new file mode 100644 index 0000000000..5fbc39be9d --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Logging/ObjectResultExecutorLoggerExtensions.cs @@ -0,0 +1,26 @@ +// 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. + +using System; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNet.Mvc.Logging +{ + public static class ObjectResultExecutorLoggerExtensions + { + private static Action _objectResultExecuting; + + static ObjectResultExecutorLoggerExtensions() + { + _objectResultExecuting = LoggerMessage.Define( + LogLevel.Information, + 1, + "Executing ObjectResult, writing value {Value}."); + } + + public static void ObjectResultExecuting(this ILogger logger, object value) + { + _objectResultExecuting(logger, Convert.ToString(value), null); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/Logging/RedirectResultLoggerExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/Logging/RedirectResultLoggerExtensions.cs new file mode 100644 index 0000000000..e91ab83be8 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Logging/RedirectResultLoggerExtensions.cs @@ -0,0 +1,26 @@ +// 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. + +using System; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNet.Mvc.Logging +{ + public static class RedirectResultLoggerExtensions + { + private static Action _redirectResultExecuting; + + static RedirectResultLoggerExtensions() + { + _redirectResultExecuting = LoggerMessage.Define( + LogLevel.Information, + 1, + "Executing RedirectResult, redirecting to {Destination}."); + } + + public static void RedirectResultExecuting(this ILogger logger, string destination) + { + _redirectResultExecuting(logger, destination, null); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/Logging/RedirectToActionResultLoggerExtension.cs b/src/Microsoft.AspNet.Mvc.Core/Logging/RedirectToActionResultLoggerExtension.cs new file mode 100644 index 0000000000..a19a115516 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Logging/RedirectToActionResultLoggerExtension.cs @@ -0,0 +1,26 @@ +// 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. + +using System; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNet.Mvc.Logging +{ + public static class RedirectToActionResultLoggerExtensions + { + private static Action _redirectToActionResultExecuting; + + static RedirectToActionResultLoggerExtensions() + { + _redirectToActionResultExecuting = LoggerMessage.Define( + LogLevel.Information, + 1, + "Executing RedirectResult, redirecting to {Destination}."); + } + + public static void RedirectToActionResultExecuting(this ILogger logger, string destination) + { + _redirectToActionResultExecuting(logger, destination, null); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/Logging/RedirectToRouteResultLoggerExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/Logging/RedirectToRouteResultLoggerExtensions.cs new file mode 100644 index 0000000000..cf9c2ecc90 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.Core/Logging/RedirectToRouteResultLoggerExtensions.cs @@ -0,0 +1,26 @@ +// 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. + +using System; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNet.Mvc.Logging +{ + public static class RedirectToRouteResultLoggerExtensions + { + private static Action _redirectToRouteResultExecuting; + + static RedirectToRouteResultLoggerExtensions() + { + _redirectToRouteResultExecuting = LoggerMessage.Define( + LogLevel.Information, + 1, + "Executing RedirectToRouteResult, redirecting to {Destination} from route {RouteName}."); + } + + public static void RedirectToRouteResultExecuting(this ILogger logger, string destination, string routeName) + { + _redirectToRouteResultExecuting(logger, destination, routeName, null); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.Core/ObjectResult.cs b/src/Microsoft.AspNet.Mvc.Core/ObjectResult.cs index 3fe3c3e7b8..d7b2baaf36 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ObjectResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ObjectResult.cs @@ -36,7 +36,9 @@ namespace Microsoft.AspNet.Mvc public override Task ExecuteResultAsync(ActionContext context) { var executor = context.HttpContext.RequestServices.GetRequiredService(); - return executor.ExecuteAsync(context, this); + var result = executor.ExecuteAsync(context, this); + + return result; } /// diff --git a/src/Microsoft.AspNet.Mvc.Core/RedirectResult.cs b/src/Microsoft.AspNet.Mvc.Core/RedirectResult.cs index 27ccf4ec33..f4c544e0b6 100644 --- a/src/Microsoft.AspNet.Mvc.Core/RedirectResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/RedirectResult.cs @@ -3,8 +3,10 @@ using System; using Microsoft.AspNet.Mvc.Core; +using Microsoft.AspNet.Mvc.Logging; using Microsoft.AspNet.Mvc.ViewFeatures; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; namespace Microsoft.AspNet.Mvc { @@ -65,6 +67,9 @@ namespace Microsoft.AspNet.Mvc throw new ArgumentNullException(nameof(context)); } + var loggerFactory = context.HttpContext.RequestServices.GetRequiredService(); + var logger = loggerFactory.CreateLogger(); + var urlHelper = GetUrlHelper(context); // IsLocalUrl is called to handle Urls starting with '~/'. @@ -74,6 +79,7 @@ namespace Microsoft.AspNet.Mvc destinationUrl = urlHelper.Content(Url); } + logger.RedirectResultExecuting(destinationUrl); context.HttpContext.Response.Redirect(destinationUrl, Permanent); } diff --git a/src/Microsoft.AspNet.Mvc.Core/RedirectToActionResult.cs b/src/Microsoft.AspNet.Mvc.Core/RedirectToActionResult.cs index 516424ea53..627a6b3216 100644 --- a/src/Microsoft.AspNet.Mvc.Core/RedirectToActionResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/RedirectToActionResult.cs @@ -4,8 +4,10 @@ using System; using System.Collections.Generic; using Microsoft.AspNet.Mvc.Core; +using Microsoft.AspNet.Mvc.Logging; using Microsoft.AspNet.Mvc.ViewFeatures; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; namespace Microsoft.AspNet.Mvc { @@ -48,6 +50,9 @@ namespace Microsoft.AspNet.Mvc throw new ArgumentNullException(nameof(context)); } + var loggerFactory = context.HttpContext.RequestServices.GetRequiredService(); + var logger = loggerFactory.CreateLogger(); + var urlHelper = GetUrlHelper(context); var destinationUrl = urlHelper.Action(ActionName, ControllerName, RouteValues); @@ -56,6 +61,7 @@ namespace Microsoft.AspNet.Mvc throw new InvalidOperationException(Resources.NoRoutesMatched); } + logger.RedirectToActionResultExecuting(destinationUrl); context.HttpContext.Response.Redirect(destinationUrl, Permanent); } diff --git a/src/Microsoft.AspNet.Mvc.Core/RedirectToRouteResult.cs b/src/Microsoft.AspNet.Mvc.Core/RedirectToRouteResult.cs index c0dfe7585e..555aff047d 100644 --- a/src/Microsoft.AspNet.Mvc.Core/RedirectToRouteResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/RedirectToRouteResult.cs @@ -4,9 +4,11 @@ using System; using System.Collections.Generic; using Microsoft.AspNet.Mvc.Core; +using Microsoft.AspNet.Mvc.Logging; using Microsoft.AspNet.Mvc.ViewFeatures; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Internal; +using Microsoft.Extensions.Logging; namespace Microsoft.AspNet.Mvc { @@ -49,6 +51,9 @@ namespace Microsoft.AspNet.Mvc throw new ArgumentNullException(nameof(context)); } + var loggerFactory = context.HttpContext.RequestServices.GetRequiredService(); + var logger = loggerFactory.CreateLogger(); + var urlHelper = GetUrlHelper(context); var destinationUrl = urlHelper.RouteUrl(RouteName, RouteValues); @@ -57,6 +62,7 @@ namespace Microsoft.AspNet.Mvc throw new InvalidOperationException(Resources.NoRoutesMatched); } + logger.RedirectToRouteResultExecuting(destinationUrl, RouteName); context.HttpContext.Response.Redirect(destinationUrl, Permanent); } diff --git a/src/Microsoft.AspNet.Mvc.Formatters.Json/JsonResult.cs b/src/Microsoft.AspNet.Mvc.Formatters.Json/JsonResult.cs index 9b26840264..c3bf2030b6 100644 --- a/src/Microsoft.AspNet.Mvc.Formatters.Json/JsonResult.cs +++ b/src/Microsoft.AspNet.Mvc.Formatters.Json/JsonResult.cs @@ -5,9 +5,11 @@ using System; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.OptionsModel; using Microsoft.Net.Http.Headers; using Newtonsoft.Json; +using Microsoft.AspNet.Mvc.Logging; namespace Microsoft.AspNet.Mvc { @@ -72,6 +74,9 @@ namespace Microsoft.AspNet.Mvc throw new ArgumentNullException(nameof(context)); } + var loggerFactory = context.HttpContext.RequestServices.GetRequiredService(); + var logger = loggerFactory.CreateLogger(); + var response = context.HttpContext.Response; var contentTypeHeader = ContentType; @@ -107,6 +112,8 @@ namespace Microsoft.AspNet.Mvc .SerializerSettings; } + logger.JsonResultExecuting(Value); + using (var writer = new HttpResponseStreamWriter(response.Body, contentTypeHeader.Encoding)) { using (var jsonWriter = new JsonTextWriter(writer)) diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/Logging/PartialViewResultExecutorLoggerExtensions.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/Logging/PartialViewResultExecutorLoggerExtensions.cs new file mode 100644 index 0000000000..411a674b86 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/Logging/PartialViewResultExecutorLoggerExtensions.cs @@ -0,0 +1,27 @@ +// 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. + +using System; +using Microsoft.AspNet.Mvc.ViewEngines; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNet.Mvc.Logging +{ + public static class PartialViewResultExecutorLoggerExtensions + { + private static Action _partialViewResultExecuting; + + static PartialViewResultExecutorLoggerExtensions() + { + _partialViewResultExecuting = LoggerMessage.Define( + LogLevel.Information, + 1, + "Executing PartialViewResult, running view at path {Path}."); + } + + public static void PartialViewResultExecuting(this ILogger logger, IView view) + { + _partialViewResultExecuting(logger, view.Path, null); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/Logging/ViewComponentResultLoggerExtensions.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/Logging/ViewComponentResultLoggerExtensions.cs new file mode 100644 index 0000000000..ce27cbaf71 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/Logging/ViewComponentResultLoggerExtensions.cs @@ -0,0 +1,49 @@ +// 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. + +using System; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNet.Mvc.Logging +{ + public static class ViewComponentResultLoggerExtensions + { + private static Action _viewComponentResultExecuting; + + static ViewComponentResultLoggerExtensions() + { + _viewComponentResultExecuting = LoggerMessage.Define( + LogLevel.Information, + 1, + "Executing ViewComponentResult, running {ViewComponentName} with arguments ({Arguments})."); + } + + public static void ViewComponentResultExecuting(this ILogger logger, string viewComponentName, object[] arguments) + { + if (logger.IsEnabled(LogLevel.Information)) + { + var formattedArguments = new string[arguments.Length]; + for (var i = 0; i < arguments.Length; i++) + { + formattedArguments[i] = Convert.ToString(arguments[i]); + } + + _viewComponentResultExecuting(logger, viewComponentName, formattedArguments, null); + } + } + + public static void ViewComponentResultExecuting(this ILogger logger, Type viewComponentType, object[] arguments) + { + if (logger.IsEnabled(LogLevel.Information)) + { + var formattedArguments = new string[arguments.Length]; + for (var i = 0; i < arguments.Length; i++) + { + formattedArguments[i] = Convert.ToString(arguments[i]); + } + + _viewComponentResultExecuting(logger, viewComponentType.Name, formattedArguments, null); + } + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/Logging/ViewResultExecutorLoggerExtensions.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/Logging/ViewResultExecutorLoggerExtensions.cs new file mode 100644 index 0000000000..17ad2ca211 --- /dev/null +++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/Logging/ViewResultExecutorLoggerExtensions.cs @@ -0,0 +1,27 @@ +// 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. + +using System; +using Microsoft.AspNet.Mvc.ViewEngines; +using Microsoft.Extensions.Logging; + +namespace Microsoft.AspNet.Mvc.Logging +{ + public static class ViewResultExecutorLoggerExtensions + { + private static Action _viewResultExecuting; + + static ViewResultExecutorLoggerExtensions() + { + _viewResultExecuting = LoggerMessage.Define( + LogLevel.Information, + 1, + "Executing ViewResult, running view at path {Path}."); + } + + public static void ViewResultExecuting(this ILogger logger, IView view) + { + _viewResultExecuting(logger, view.Path, null); + } + } +} diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewComponentResult.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewComponentResult.cs index 1e75291920..6343cbccd6 100644 --- a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewComponentResult.cs +++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewComponentResult.cs @@ -4,12 +4,14 @@ using System; using System.Text; using System.Threading.Tasks; +using Microsoft.AspNet.Mvc.Logging; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.Rendering; using Microsoft.AspNet.Mvc.ViewEngines; using Microsoft.AspNet.Mvc.ViewFeatures; using Microsoft.AspNet.Mvc.ViewFeatures.Internal; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.OptionsModel; using Microsoft.Net.Http.Headers; @@ -72,6 +74,9 @@ namespace Microsoft.AspNet.Mvc var htmlHelperOptions = services.GetRequiredService>().Value.HtmlHelperOptions; var viewComponentHelper = services.GetRequiredService(); + var loggerFactory = services.GetRequiredService(); + var logger = loggerFactory.CreateLogger(); + var viewData = ViewData; if (viewData == null) { @@ -124,10 +129,12 @@ namespace Microsoft.AspNet.Mvc } else if (ViewComponentType == null) { + logger.ViewComponentResultExecuting(ViewComponentName, Arguments); await viewComponentHelper.RenderInvokeAsync(ViewComponentName, Arguments); } else { + logger.ViewComponentResultExecuting(ViewComponentType, Arguments); await viewComponentHelper.RenderInvokeAsync(ViewComponentType, Arguments); } } diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/PartialViewResultExecutor.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/PartialViewResultExecutor.cs index 0ecb853c85..b6eecbc153 100644 --- a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/PartialViewResultExecutor.cs +++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/PartialViewResultExecutor.cs @@ -5,6 +5,7 @@ using System; using System.Diagnostics; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Infrastructure; +using Microsoft.AspNet.Mvc.Logging; using Microsoft.AspNet.Mvc.ViewEngines; using Microsoft.Extensions.Logging; using Microsoft.Extensions.OptionsModel; @@ -134,6 +135,8 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures throw new ArgumentNullException(nameof(viewResult)); } + Logger.PartialViewResultExecuting(view); + return ExecuteAsync( actionContext, view, diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/ViewResultExecutor.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/ViewResultExecutor.cs index 74f96731b3..9f96afe837 100644 --- a/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/ViewResultExecutor.cs +++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/ViewFeatures/ViewResultExecutor.cs @@ -5,6 +5,7 @@ using System; using System.Diagnostics; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Infrastructure; +using Microsoft.AspNet.Mvc.Logging; using Microsoft.AspNet.Mvc.ViewEngines; using Microsoft.Extensions.Logging; using Microsoft.Extensions.OptionsModel; @@ -134,6 +135,9 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures throw new ArgumentNullException(nameof(viewResult)); } + + Logger.ViewResultExecuting(view); + return ExecuteAsync( actionContext, view, diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ChallengeResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ChallengeResultTest.cs index d24a5910d8..d70ae18f46 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ChallengeResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ChallengeResultTest.cs @@ -6,6 +6,9 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Authentication; using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Routing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Moq; using Xunit; @@ -18,7 +21,10 @@ namespace Microsoft.AspNet.Mvc { // Arrange var result = new ChallengeResult("", null); + var httpContext = new Mock(); + httpContext.SetupGet(c => c.RequestServices).Returns(CreateServices().BuildServiceProvider()); + var auth = new Mock(); httpContext.Setup(o => o.Authentication).Returns(auth.Object); @@ -41,7 +47,10 @@ namespace Microsoft.AspNet.Mvc { // Arrange var result = new ChallengeResult(new string[] { }, null); + var httpContext = new Mock(); + httpContext.SetupGet(c => c.RequestServices).Returns(CreateServices().BuildServiceProvider()); + var auth = new Mock(); httpContext.Setup(o => o.Authentication).Returns(auth.Object); @@ -58,5 +67,12 @@ namespace Microsoft.AspNet.Mvc // Assert auth.Verify(c => c.ChallengeAsync((AuthenticationProperties)null), Times.Exactly(1)); } + + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + services.AddInstance(NullLoggerFactory.Instance); + return services; + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ContentResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ContentResultTest.cs index 6d9addecfd..51f4d7ad9c 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ContentResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ContentResultTest.cs @@ -9,7 +9,11 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Features; using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.Abstractions; +using Microsoft.AspNet.Mvc.ViewComponents; using Microsoft.AspNet.Routing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Microsoft.Net.Http.Headers; using Moq; using Xunit; @@ -94,7 +98,7 @@ namespace Microsoft.AspNet.Mvc Encoding = Encoding.ASCII } }; - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); httpContext.Features.Set(new TestBufferingFeature()); var memoryStream = new MemoryStream(); httpContext.Response.Body = memoryStream; @@ -215,9 +219,21 @@ namespace Microsoft.AspNet.Mvc new ActionDescriptor()); } + private static IServiceCollection CreateServices(params ViewComponentDescriptor[] descriptors) + { + var services = new ServiceCollection(); + services.AddInstance(NullLoggerFactory.Instance); + return services; + } + private static HttpContext GetHttpContext() { - return new DefaultHttpContext(); + var services = CreateServices(); + + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); + + return httpContext; } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Controllers/ControllerActionInvokerTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Controllers/ControllerActionInvokerTest.cs index 62e852c536..9f99e9b98a 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Controllers/ControllerActionInvokerTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Controllers/ControllerActionInvokerTest.cs @@ -18,6 +18,7 @@ using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.ModelBinding.Validation; using Microsoft.AspNet.Routing; using Microsoft.AspNet.Testing; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Testing; using Microsoft.Extensions.OptionsModel; @@ -1976,13 +1977,17 @@ namespace Microsoft.AspNet.Mvc.Controllers } var httpContext = new Mock(MockBehavior.Loose); - var httpRequest = new DefaultHttpContext().Request; - var httpResponse = new DefaultHttpContext().Response; + + var http = GetHttpContext(); + + var httpRequest = http.Request; + var httpResponse = http.Response; httpContext.SetupGet(c => c.Request).Returns(httpRequest); httpContext.SetupGet(c => c.Response).Returns(httpResponse); - httpContext.Setup(o => o.RequestServices.GetService(typeof(ILogger))) - .Returns(new Mock>().Object); + httpContext + .Setup(o => o.RequestServices.GetService(typeof(ILoggerFactory))) + .Returns(NullLoggerFactory.Instance); httpResponse.Body = new MemoryStream(); @@ -2136,6 +2141,25 @@ namespace Microsoft.AspNet.Mvc.Controllers throw _actionException; } + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + + services.AddInstance(NullLoggerFactory.Instance); + + return services; + } + + private static HttpContext GetHttpContext() + { + var services = CreateServices(); + + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); + + return httpContext; + } + public IActionResult ActionMethodWithBodyParameter([FromBody] Person bodyParam) { return new ObjectResult(bodyParam); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/FileContentResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/FileContentResultTest.cs index 17adde2290..bee4d82d29 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/FileContentResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/FileContentResultTest.cs @@ -3,10 +3,14 @@ using System.IO; using System.Threading.Tasks; +using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Features; using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Routing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Microsoft.Net.Http.Headers; using Xunit; @@ -33,7 +37,7 @@ namespace Microsoft.AspNet.Mvc // Arrange var buffer = new byte[] { 1, 2, 3, 4, 5 }; - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); var outStream = new MemoryStream(); httpContext.Response.Body = outStream; @@ -56,7 +60,7 @@ namespace Microsoft.AspNet.Mvc var expectedContentType = "text/foo; charset=us-ascii"; var buffer = new byte[] { 1, 2, 3, 4, 5 }; - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); var outStream = new MemoryStream(); httpContext.Response.Body = outStream; @@ -80,7 +84,7 @@ namespace Microsoft.AspNet.Mvc var expectedContentType = "text/foo; charset=us-ascii"; var buffer = new byte[] { 1, 2, 3, 4, 5 }; - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); var bufferingFeature = new TestBufferingFeature(); httpContext.Features.Set(bufferingFeature); var outStream = new MemoryStream(); @@ -99,6 +103,25 @@ namespace Microsoft.AspNet.Mvc Assert.True(bufferingFeature.DisableResponseBufferingInvoked); } + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + + services.AddInstance(NullLoggerFactory.Instance); + + return services; + } + + private static HttpContext GetHttpContext() + { + var services = CreateServices(); + + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); + + return httpContext; + } + private class TestBufferingFeature : IHttpBufferingFeature { public bool DisableResponseBufferingInvoked { get; private set; } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/FileResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/FileResultTest.cs index 63057caa1e..8356184a9a 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/FileResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/FileResultTest.cs @@ -8,6 +8,9 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Routing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Microsoft.Net.Http.Headers; using Moq; using Xunit; @@ -32,7 +35,7 @@ namespace Microsoft.AspNet.Mvc // See comment in FileResult.cs detailing how the FileDownloadName should be encoded. // Arrange - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); var actionContext = CreateActionContext(httpContext); var result = new EmptyFileResult("application/my-type") @@ -54,7 +57,7 @@ namespace Microsoft.AspNet.Mvc public async Task ContentDispositionHeader_IsEncodedCorrectly_ForUnicodeCharacters() { // Arrange - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); var actionContext = CreateActionContext(httpContext); var result = new EmptyFileResult("application/my-type") @@ -77,8 +80,12 @@ namespace Microsoft.AspNet.Mvc { // Arrange var httpContext = new Mock(MockBehavior.Strict); + httpContext.SetupSet(c => c.Response.ContentType = "application/my-type").Verifiable(); httpContext.Setup(c => c.Response.Body).Returns(Stream.Null); + httpContext + .Setup(c => c.RequestServices.GetService(typeof(ILoggerFactory))) + .Returns(NullLoggerFactory.Instance); var actionContext = CreateActionContext(httpContext.Object); @@ -96,7 +103,7 @@ namespace Microsoft.AspNet.Mvc public async Task ExecuteResultAsync_SetsContentDisposition_IfSpecified() { // Arrange - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); var actionContext = CreateActionContext(httpContext); var result = new EmptyFileResult("application/my-type") @@ -207,6 +214,23 @@ namespace Microsoft.AspNet.Mvc Assert.Equal(expectedOutput, actual); } + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + services.AddInstance(NullLoggerFactory.Instance); + return services; + } + + private static HttpContext GetHttpContext() + { + var services = CreateServices(); + + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); + + return httpContext; + } + private static ActionContext CreateActionContext(HttpContext context) { return new ActionContext(context, new RouteData(), new ActionDescriptor()); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/FileStreamResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/FileStreamResultTest.cs index 0470b7692f..edd2a31ea5 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/FileStreamResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/FileStreamResultTest.cs @@ -6,10 +6,14 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Features; using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Routing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Microsoft.Net.Http.Headers; using Moq; using Xunit; @@ -52,7 +56,7 @@ namespace Microsoft.AspNet.Mvc var result = new FileStreamResult(mockReadStream.Object, "text/plain"); - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); httpContext.Response.Body = mockBodyStream.Object; var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); @@ -76,7 +80,7 @@ namespace Microsoft.AspNet.Mvc var originalStream = new MemoryStream(originalBytes); - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); var outStream = new MemoryStream(); httpContext.Response.Body = outStream; @@ -104,7 +108,7 @@ namespace Microsoft.AspNet.Mvc var originalStream = new MemoryStream(originalBytes); - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); var outStream = new MemoryStream(); httpContext.Response.Body = outStream; @@ -130,7 +134,7 @@ namespace Microsoft.AspNet.Mvc var originalStream = new MemoryStream(expected); - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); var bufferingFeature = new TestBufferingFeature(); httpContext.Features.Set(bufferingFeature); var outStream = new MemoryStream(); @@ -148,5 +152,22 @@ namespace Microsoft.AspNet.Mvc Assert.Equal(expectedContentType, httpContext.Response.ContentType); Assert.True(bufferingFeature.DisableResponseBufferingInvoked); } + + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + services.AddInstance(NullLoggerFactory.Instance); + return services; + } + + private static HttpContext GetHttpContext() + { + var services = CreateServices(); + + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); + + return httpContext; + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/HttpOkResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/HttpOkResultTest.cs index a0fb90f234..43aa121c18 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/HttpOkResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/HttpOkResultTest.cs @@ -6,6 +6,9 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Routing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Xunit; namespace Microsoft.AspNet.Mvc @@ -26,7 +29,10 @@ namespace Microsoft.AspNet.Mvc public async Task HttpOkResult_SetsStatusCode() { // Arrange - var context = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()); + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = CreateServices().BuildServiceProvider(); + + var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); var result = new HttpOkResult(); // Act @@ -35,5 +41,12 @@ namespace Microsoft.AspNet.Mvc // Assert Assert.Equal(StatusCodes.Status200OK, context.HttpContext.Response.StatusCode); } + + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + services.AddInstance(NullLoggerFactory.Instance); + return services; + } } } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/HttpStatusCodeResultTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/HttpStatusCodeResultTests.cs index bed9dce54c..79ab2021e6 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/HttpStatusCodeResultTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/HttpStatusCodeResultTests.cs @@ -5,6 +5,9 @@ using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Routing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Xunit; namespace Microsoft.AspNet.Mvc @@ -17,7 +20,7 @@ namespace Microsoft.AspNet.Mvc // Arrange var result = new HttpStatusCodeResult(StatusCodes.Status404NotFound); - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); var routeData = new RouteData(); var actionDescriptor = new ActionDescriptor(); @@ -29,5 +32,22 @@ namespace Microsoft.AspNet.Mvc // Assert Assert.Equal(StatusCodes.Status404NotFound, httpContext.Response.StatusCode); } + + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + services.AddInstance(NullLoggerFactory.Instance); + return services; + } + + private static HttpContext GetHttpContext() + { + var services = CreateServices(); + + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); + + return httpContext; + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Infrastructure/ObjectResultExecutorTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Infrastructure/ObjectResultExecutorTest.cs index 21ec92c7df..142fa5b9be 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Infrastructure/ObjectResultExecutorTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Infrastructure/ObjectResultExecutorTest.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.Formatters; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Testing; using Microsoft.Extensions.OptionsModel; @@ -259,7 +260,7 @@ namespace Microsoft.AspNet.Mvc.Infrastructure var actionContext = new ActionContext() { - HttpContext = new DefaultHttpContext(), + HttpContext = GetHttpContext(), }; var result = new ObjectResult("someValue"); @@ -284,7 +285,7 @@ namespace Microsoft.AspNet.Mvc.Infrastructure var actionContext = new ActionContext() { - HttpContext = new DefaultHttpContext(), + HttpContext = GetHttpContext(), }; var result = new ObjectResult("someValue"); @@ -353,7 +354,7 @@ namespace Microsoft.AspNet.Mvc.Infrastructure var actionContext = new ActionContext() { - HttpContext = new DefaultHttpContext(), + HttpContext = GetHttpContext(), }; actionContext.HttpContext.Request.Headers[HeaderNames.Accept] = acceptHeader; @@ -390,7 +391,7 @@ namespace Microsoft.AspNet.Mvc.Infrastructure var actionContext = new ActionContext() { - HttpContext = new DefaultHttpContext(), + HttpContext = GetHttpContext(), }; actionContext.HttpContext.Request.Headers[HeaderNames.Accept] = acceptHeader; @@ -401,6 +402,25 @@ namespace Microsoft.AspNet.Mvc.Infrastructure Assert.Equal(expectedContentType, actionContext.HttpContext.Response.Headers[HeaderNames.ContentType]); } + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + + services.AddInstance(NullLoggerFactory.Instance); + + return services; + } + + private static HttpContext GetHttpContext() + { + var services = CreateServices(); + + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); + + return httpContext; + } + private static TestObjectResultExecutor CreateExecutor( IOptions options = null, ActionBindingContext bindingContext = null) diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ObjectResultTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ObjectResultTests.cs index 103d95085d..bd49125f55 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ObjectResultTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ObjectResultTests.cs @@ -8,6 +8,7 @@ using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.Formatters; using Microsoft.AspNet.Mvc.Infrastructure; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Testing; using Microsoft.Net.Http.Headers; using Xunit; @@ -68,6 +69,7 @@ namespace Microsoft.AspNet.Mvc new TestOptionsManager(), new ActionBindingContextAccessor(), NullLoggerFactory.Instance)); + services.AddInstance(NullLoggerFactory.Instance); return services.BuildServiceProvider(); } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/PhysicalFileResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/PhysicalFileResultTest.cs index 1b37f44f4f..26c35ab875 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/PhysicalFileResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/PhysicalFileResultTest.cs @@ -6,10 +6,14 @@ using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Features; using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Routing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Microsoft.Net.Http.Headers; using Moq; using Xunit; @@ -37,7 +41,7 @@ namespace Microsoft.AspNet.Mvc // Arrange var path = Path.GetFullPath(Path.Combine("TestFiles", "FilePathResultTestFile.txt")); var result = new TestPhysicalFileResult(path, "text/plain"); - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); httpContext.Response.Body = new MemoryStream(); var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); @@ -62,7 +66,7 @@ namespace Microsoft.AspNet.Mvc .Setup(s => s.SendFileAsync(path, 0, null, CancellationToken.None)) .Returns(Task.FromResult(0)); - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); httpContext.Features.Set(sendFileMock.Object); var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); @@ -83,7 +87,7 @@ namespace Microsoft.AspNet.Mvc { IsAscii = true }; - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); var memoryStream = new MemoryStream(); httpContext.Response.Body = memoryStream; var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); @@ -104,7 +108,7 @@ namespace Microsoft.AspNet.Mvc var path = Path.GetFullPath(Path.Combine(".", "TestFiles", "FilePathResultTestFile.txt")); var result = new TestPhysicalFileResult(path, "text/plain"); - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); httpContext.Response.Body = new MemoryStream(); var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); @@ -136,7 +140,7 @@ namespace Microsoft.AspNet.Mvc { // Arrange var result = new TestPhysicalFileResult(path, "text/plain"); - var context = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()); + var context = new ActionContext(GetHttpContext(), new RouteData(), new ActionDescriptor()); var expectedMessage = $"Path '{path}' was not rooted."; // Act @@ -204,5 +208,22 @@ namespace Microsoft.AspNet.Mvc } } } + + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + services.AddInstance(NullLoggerFactory.Instance); + return services; + } + + private static HttpContext GetHttpContext() + { + var services = CreateServices(); + + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); + + return httpContext; + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/RedirectResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/RedirectResultTest.cs index 069f09ad71..53b4802ecc 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/RedirectResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/RedirectResultTest.cs @@ -8,6 +8,7 @@ using Microsoft.AspNet.Mvc.Infrastructure; using Microsoft.AspNet.Mvc.Routing; using Microsoft.AspNet.Routing; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Moq; using Xunit; @@ -110,6 +111,7 @@ namespace Microsoft.AspNet.Mvc { var serviceCollection = new ServiceCollection(); serviceCollection.AddInstance(urlHelper); + serviceCollection.AddTransient(); return serviceCollection.BuildServiceProvider(); } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/RedirectToActionResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/RedirectToActionResultTest.cs index 62092c8a73..54497278b8 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/RedirectToActionResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/RedirectToActionResultTest.cs @@ -8,6 +8,9 @@ using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Mvc.Routing; using Microsoft.AspNet.Routing; using Microsoft.AspNet.Testing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Moq; using Xunit; @@ -21,13 +24,19 @@ namespace Microsoft.AspNet.Mvc // Arrange var expectedUrl = "SampleAction"; var expectedPermanentFlag = false; - var httpContext = new Mock(); - var httpResponse = new Mock(); - httpContext.Setup(o => o.Response).Returns(httpResponse.Object); - var actionContext = new ActionContext(httpContext.Object, - new RouteData(), - new ActionDescriptor()); + var httpContext = new Mock(); + httpContext + .SetupGet(o => o.RequestServices) + .Returns(CreateServices().BuildServiceProvider()); + + var httpResponse = new Mock(); + httpContext + .Setup(o => o.Response) + .Returns(httpResponse.Object); + + var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor()); + var urlHelper = GetMockUrlHelper(expectedUrl); var result = new RedirectToActionResult("SampleAction", null, null) { @@ -49,10 +58,14 @@ namespace Microsoft.AspNet.Mvc { // Arrange var httpContext = new Mock(); - httpContext.Setup(o => o.Response).Returns(new Mock().Object); - var actionContext = new ActionContext(httpContext.Object, - new RouteData(), - new ActionDescriptor()); + httpContext + .Setup(o => o.Response) + .Returns(new Mock().Object); + httpContext + .SetupGet(o => o.RequestServices) + .Returns(CreateServices().BuildServiceProvider()); + + var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor()); var urlHelper = GetMockUrlHelper(returnValue: null); var result = new RedirectToActionResult(null, null, null) @@ -76,5 +89,12 @@ namespace Microsoft.AspNet.Mvc return urlHelper.Object; } + + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + services.AddInstance(NullLoggerFactory.Instance); + return services; + } } } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/RedirectToRouteResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/RedirectToRouteResultTest.cs index 5e32505eb0..13466c0a05 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/RedirectToRouteResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/RedirectToRouteResultTest.cs @@ -10,7 +10,10 @@ using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Mvc.Routing; using Microsoft.AspNet.Routing; using Microsoft.AspNet.Testing; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Internal; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Moq; using Xunit; @@ -25,7 +28,10 @@ namespace Microsoft.AspNet.Mvc // Arrange var expectedUrl = "SampleAction"; var expectedPermanentFlag = false; + var httpContext = new Mock(); + httpContext.SetupGet(o => o.RequestServices).Returns(CreateServices().BuildServiceProvider()); + var httpResponse = new Mock(); httpContext.Setup(o => o.Response).Returns(httpResponse.Object); @@ -54,10 +60,14 @@ namespace Microsoft.AspNet.Mvc { // Arrange var httpContext = new Mock(); - httpContext.Setup(o => o.Response).Returns(new Mock().Object); - var actionContext = new ActionContext(httpContext.Object, - new RouteData(), - new ActionDescriptor()); + httpContext + .Setup(o => o.Response) + .Returns(new Mock().Object); + httpContext + .SetupGet(o => o.RequestServices) + .Returns(CreateServices().BuildServiceProvider()); + + var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor()); var urlHelper = GetMockUrlHelper(returnValue: null); var result = new RedirectToRouteResult(null, new Dictionary()) @@ -86,10 +96,16 @@ namespace Microsoft.AspNet.Mvc .Verifiable(); var serviceProvider = new Mock(); - serviceProvider.Setup(sp => sp.GetService(typeof(IUrlHelper))) + serviceProvider + .Setup(sp => sp.GetService(typeof(IUrlHelper))) .Returns(urlHelper.Object); - var httpContext = new DefaultHttpContext(); + serviceProvider + .Setup(sp => sp.GetService(typeof(ILoggerFactory))) + .Returns(NullLoggerFactory.Instance); + + var httpContext = GetHttpContext(); httpContext.RequestServices = serviceProvider.Object; + var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); var result = new RedirectToRouteResult(routeName, new { id = 10 }); @@ -103,6 +119,23 @@ namespace Microsoft.AspNet.Mvc Assert.Equal(locationUrl, httpContext.Response.Headers["Location"]); } + private static HttpContext GetHttpContext() + { + var services = CreateServices(); + + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); + + return httpContext; + } + + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + services.AddInstance(NullLoggerFactory.Instance); + return services; + } + public static IEnumerable RedirectToRouteData { get diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/VirtualFileResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/VirtualFileResultTest.cs index 87efa71b51..e606e82699 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/VirtualFileResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/VirtualFileResultTest.cs @@ -7,11 +7,14 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNet.FileProviders; using Microsoft.AspNet.Hosting; +using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Features; using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Routing; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Microsoft.Net.Http.Headers; using Moq; using Xunit; @@ -44,10 +47,11 @@ namespace Microsoft.AspNet.Mvc appEnvironment.Setup(app => app.WebRootFileProvider) .Returns(GetFileProvider(path)); - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); httpContext.Response.Body = new MemoryStream(); httpContext.RequestServices = new ServiceCollection() .AddInstance(appEnvironment.Object) + .AddTransient() .BuildServiceProvider(); var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); @@ -71,7 +75,7 @@ namespace Microsoft.AspNet.Mvc FileProvider = GetFileProvider(path), }; - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); httpContext.Response.Body = new MemoryStream(); var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); @@ -100,7 +104,7 @@ namespace Microsoft.AspNet.Mvc .Setup(s => s.SendFileAsync(path, 0, null, CancellationToken.None)) .Returns(Task.FromResult(0)); - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); httpContext.Features.Set(sendFileMock.Object); var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); @@ -123,7 +127,7 @@ namespace Microsoft.AspNet.Mvc IsAscii = true, }; - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); var memoryStream = new MemoryStream(); httpContext.Response.Body = memoryStream; var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); @@ -147,7 +151,7 @@ namespace Microsoft.AspNet.Mvc FileProvider = GetFileProvider(path), }; - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); httpContext.Response.Body = new MemoryStream(); var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); @@ -175,7 +179,7 @@ namespace Microsoft.AspNet.Mvc { FileProvider = GetFileProvider(path), }; - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); var memoryStream = new MemoryStream(); httpContext.Response.Body = memoryStream; @@ -194,7 +198,7 @@ namespace Microsoft.AspNet.Mvc public async Task ExecuteResultAsync_WorksWithNonDiskBasedFiles() { // Arrange - var httpContext = new DefaultHttpContext(); + var httpContext = GetHttpContext(); httpContext.Response.Body = new MemoryStream(); var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); var expectedData = "This is an embedded resource"; @@ -249,7 +253,7 @@ namespace Microsoft.AspNet.Mvc }; var expectedMessage = "Could not find file: " + path; - var context = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()); + var context = new ActionContext(GetHttpContext(), new RouteData(), new ActionDescriptor()); // Act var ex = await Assert.ThrowsAsync(() => filePathResult.ExecuteResultAsync(context)); @@ -286,6 +290,25 @@ namespace Microsoft.AspNet.Mvc Assert.ThrowsAsync(() => filePathResult.ExecuteResultAsync(context)); } + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + + services.AddInstance(NullLoggerFactory.Instance); + + return services; + } + + private static HttpContext GetHttpContext() + { + var services = CreateServices(); + + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); + + return httpContext; + } + private IFileProvider GetFileProvider(string path) { var fileInfo = new Mock(); diff --git a/test/Microsoft.AspNet.Mvc.Cors.Test/CorsAuthorizationFilterTest.cs b/test/Microsoft.AspNet.Mvc.Cors.Test/CorsAuthorizationFilterTest.cs index d0bb398bd3..6267de105a 100644 --- a/test/Microsoft.AspNet.Mvc.Cors.Test/CorsAuthorizationFilterTest.cs +++ b/test/Microsoft.AspNet.Mvc.Cors.Test/CorsAuthorizationFilterTest.cs @@ -11,6 +11,9 @@ using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Mvc.Filters; using Microsoft.AspNet.Routing; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Moq; using Xunit; @@ -140,6 +143,10 @@ namespace Microsoft.AspNet.Mvc.Cors httpContext.Request.Headers.Add(CorsConstants.Origin, new[] { headers.Origin }); } + var services = new ServiceCollection(); + services.AddInstance(NullLoggerFactory.Instance); + httpContext.RequestServices = services.BuildServiceProvider(); + var method = isPreflight ? CorsConstants.PreflightHttpMethod : "GET"; httpContext.Request.Method = method; diff --git a/test/Microsoft.AspNet.Mvc.Formatters.Json.Test/JsonResultTest.cs b/test/Microsoft.AspNet.Mvc.Formatters.Json.Test/JsonResultTest.cs index 04311bc12a..3855d1b32b 100644 --- a/test/Microsoft.AspNet.Mvc.Formatters.Json.Test/JsonResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Formatters.Json.Test/JsonResultTest.cs @@ -11,6 +11,8 @@ using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Routing; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Microsoft.Net.Http.Headers; using Newtonsoft.Json; using Xunit; @@ -128,8 +130,10 @@ namespace Microsoft.AspNet.Mvc { var httpContext = new DefaultHttpContext(); httpContext.Response.Body = new MemoryStream(); + var services = new ServiceCollection(); services.AddOptions(); + services.AddInstance(NullLoggerFactory.Instance); httpContext.RequestServices = services.BuildServiceProvider(); return httpContext; diff --git a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/PartialViewResultTest.cs b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/PartialViewResultTest.cs index 34a60f62cf..163647bff7 100644 --- a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/PartialViewResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/PartialViewResultTest.cs @@ -75,6 +75,11 @@ namespace Microsoft.AspNet.Mvc .Setup(v => v.Dispose()) .Verifiable(); + // Used by logging + view + .SetupGet(v => v.Path) + .Returns("myview.cshtml"); + var viewEngine = new Mock(MockBehavior.Strict); viewEngine .Setup(e => e.FindPartialView(context, "myview")) diff --git a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/ViewComponentResultTest.cs b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/ViewComponentResultTest.cs index 2530fa4d89..f9185f9eba 100644 --- a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/ViewComponentResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/ViewComponentResultTest.cs @@ -16,6 +16,8 @@ using Microsoft.AspNet.Mvc.ViewComponents; using Microsoft.AspNet.Mvc.ViewFeatures; using Microsoft.AspNet.Routing; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; using Microsoft.Extensions.OptionsModel; using Microsoft.Net.Http.Headers; using Xunit; @@ -397,6 +399,7 @@ namespace Microsoft.AspNet.Mvc services.AddSingleton(); services.AddInstance(new FixedSetViewComponentDescriptorProvider(descriptors)); services.AddSingleton(); + services.AddInstance(NullLoggerFactory.Instance); return services; } diff --git a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/ViewResultTest.cs b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/ViewResultTest.cs index 9631e4b639..f023257827 100644 --- a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/ViewResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/ViewResultTest.cs @@ -75,6 +75,10 @@ namespace Microsoft.AspNet.Mvc .Setup(v => v.Dispose()) .Verifiable(); + view + .Setup(v => v.Path) + .Returns("//location"); + var viewEngine = new Mock(MockBehavior.Strict); viewEngine .Setup(e => e.FindView(context, "myview")) diff --git a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ConflictResultTest.cs b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ConflictResultTest.cs index 6aa308a360..e9ff268cbf 100644 --- a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ConflictResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/ConflictResultTest.cs @@ -7,6 +7,9 @@ using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc; using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Routing; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; +using Microsoft.Framework.DependencyInjection; using Xunit; namespace System.Web.Http @@ -17,7 +20,7 @@ namespace System.Web.Http public async Task ConflictResult_SetsStatusCode() { // Arrange - var context = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()); + var context = new ActionContext(GetHttpContext(), new RouteData(), new ActionDescriptor()); var result = new ConflictResult(); // Act @@ -26,5 +29,24 @@ namespace System.Web.Http // Assert Assert.Equal(StatusCodes.Status409Conflict, context.HttpContext.Response.StatusCode); } + + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + + services.AddInstance(NullLoggerFactory.Instance); + + return services; + } + + private static HttpContext GetHttpContext() + { + var services = CreateServices(); + + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); + + return httpContext; + } } } diff --git a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/InternalServerErrorResultTest.cs b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/InternalServerErrorResultTest.cs index 5d0e0b0d17..222e6a22bd 100644 --- a/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/InternalServerErrorResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.WebApiCompatShimTest/InternalServerErrorResultTest.cs @@ -7,6 +7,9 @@ using Microsoft.AspNet.Http.Internal; using Microsoft.AspNet.Mvc; using Microsoft.AspNet.Mvc.Abstractions; using Microsoft.AspNet.Routing; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Testing; +using Microsoft.Framework.DependencyInjection; using Xunit; namespace System.Web.Http @@ -17,7 +20,7 @@ namespace System.Web.Http public async Task InternalServerErrorResult_SetsStatusCode() { // Arrange - var context = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor()); + var context = new ActionContext(GetHttpContext(), new RouteData(), new ActionDescriptor()); var result = new InternalServerErrorResult(); // Act @@ -26,5 +29,24 @@ namespace System.Web.Http // Assert Assert.Equal(StatusCodes.Status500InternalServerError, context.HttpContext.Response.StatusCode); } + + private static IServiceCollection CreateServices() + { + var services = new ServiceCollection(); + + services.AddInstance(NullLoggerFactory.Instance); + + return services; + } + + private static HttpContext GetHttpContext() + { + var services = CreateServices(); + + var httpContext = new DefaultHttpContext(); + httpContext.RequestServices = services.BuildServiceProvider(); + + return httpContext; + } } }