[Fixes #3274] Added DiagnosticsSource for ViewComponent
This commit is contained in:
parent
bcde82cf62
commit
624c918de5
|
|
@ -0,0 +1,87 @@
|
||||||
|
// 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.Diagnostics;
|
||||||
|
using Microsoft.AspNet.Mvc.Abstractions;
|
||||||
|
using Microsoft.AspNet.Mvc.ViewComponents;
|
||||||
|
using Microsoft.AspNet.Mvc.ViewEngines;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.Diagnostics
|
||||||
|
{
|
||||||
|
public static class ViewComponentDiagnosticSourceExtensions
|
||||||
|
{
|
||||||
|
public static void BeforeViewComponent(
|
||||||
|
this DiagnosticSource diagnosticSource,
|
||||||
|
ViewComponentContext context,
|
||||||
|
object viewComponent)
|
||||||
|
{
|
||||||
|
if (diagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.BeforeViewComponent"))
|
||||||
|
{
|
||||||
|
diagnosticSource.Write(
|
||||||
|
"Microsoft.AspNet.Mvc.BeforeViewComponent",
|
||||||
|
new
|
||||||
|
{
|
||||||
|
actionDescriptor = context.ViewContext.ActionDescriptor,
|
||||||
|
viewComponentContext = context,
|
||||||
|
viewComponent = viewComponent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AfterViewComponent(
|
||||||
|
this DiagnosticSource diagnosticSource,
|
||||||
|
ViewComponentContext context,
|
||||||
|
IViewComponentResult result,
|
||||||
|
object viewComponent)
|
||||||
|
{
|
||||||
|
if (diagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.AfterViewComponent"))
|
||||||
|
{
|
||||||
|
diagnosticSource.Write(
|
||||||
|
"Microsoft.AspNet.Mvc.AfterViewComponent",
|
||||||
|
new
|
||||||
|
{
|
||||||
|
actionDescriptor = context.ViewContext.ActionDescriptor,
|
||||||
|
viewComponentContext = context,
|
||||||
|
viewComponentResult = result,
|
||||||
|
viewComponent = viewComponent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ViewComponentBeforeViewExecute(
|
||||||
|
this DiagnosticSource diagnosticSource,
|
||||||
|
ViewComponentContext context,
|
||||||
|
IView view)
|
||||||
|
{
|
||||||
|
if (diagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.ViewComponentBeforeViewExecute"))
|
||||||
|
{
|
||||||
|
diagnosticSource.Write(
|
||||||
|
"Microsoft.AspNet.Mvc.ViewComponentBeforeViewExecute",
|
||||||
|
new
|
||||||
|
{
|
||||||
|
actionDescriptor = context.ViewContext.ActionDescriptor,
|
||||||
|
viewComponentContext = context,
|
||||||
|
view = view
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ViewComponentAfterViewExecute(
|
||||||
|
this DiagnosticSource diagnosticSource,
|
||||||
|
ViewComponentContext context,
|
||||||
|
IView view)
|
||||||
|
{
|
||||||
|
if (diagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.ViewComponentAfterViewExecute"))
|
||||||
|
{
|
||||||
|
diagnosticSource.Write(
|
||||||
|
"Microsoft.AspNet.Mvc.ViewComponentAfterViewExecute",
|
||||||
|
new
|
||||||
|
{
|
||||||
|
actionDescriptor = context.ViewContext.ActionDescriptor,
|
||||||
|
viewComponentContext = context,
|
||||||
|
view = view
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
|
using Microsoft.AspNet.Mvc.ViewEngines;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.Diagnostics
|
||||||
|
{
|
||||||
|
public static class ViewExecutorDiagnosticSourceExtensions
|
||||||
|
{
|
||||||
|
public static void BeforeView(
|
||||||
|
this DiagnosticSource diagnosticSource,
|
||||||
|
IView view,
|
||||||
|
ViewContext viewContext)
|
||||||
|
{
|
||||||
|
if (diagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.BeforeView"))
|
||||||
|
{
|
||||||
|
diagnosticSource.Write(
|
||||||
|
"Microsoft.AspNet.Mvc.BeforeView",
|
||||||
|
new { view = view, viewContext = viewContext, });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AfterView(
|
||||||
|
this DiagnosticSource diagnosticSource,
|
||||||
|
IView view,
|
||||||
|
ViewContext viewContext)
|
||||||
|
{
|
||||||
|
if (diagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.AfterView"))
|
||||||
|
{
|
||||||
|
diagnosticSource.Write(
|
||||||
|
"Microsoft.AspNet.Mvc.AfterView",
|
||||||
|
new { view = view, viewContext = viewContext, });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ViewFound(
|
||||||
|
this DiagnosticSource diagnosticSource,
|
||||||
|
ActionContext actionContext,
|
||||||
|
bool isPartial,
|
||||||
|
PartialViewResult viewResult,
|
||||||
|
string viewName,
|
||||||
|
IView view)
|
||||||
|
{
|
||||||
|
if (diagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.ViewFound"))
|
||||||
|
{
|
||||||
|
diagnosticSource.Write(
|
||||||
|
"Microsoft.AspNet.Mvc.ViewFound",
|
||||||
|
new
|
||||||
|
{
|
||||||
|
actionContext = actionContext,
|
||||||
|
isPartial = isPartial,
|
||||||
|
result = viewResult,
|
||||||
|
viewName = viewName,
|
||||||
|
view = view,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ViewNotFound(
|
||||||
|
this DiagnosticSource diagnosticSource,
|
||||||
|
ActionContext actionContext,
|
||||||
|
bool isPartial,
|
||||||
|
PartialViewResult viewResult,
|
||||||
|
string viewName,
|
||||||
|
IEnumerable<string> searchedLocations)
|
||||||
|
{
|
||||||
|
if (diagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.ViewNotFound"))
|
||||||
|
{
|
||||||
|
diagnosticSource.Write(
|
||||||
|
"Microsoft.AspNet.Mvc.ViewNotFound",
|
||||||
|
new
|
||||||
|
{
|
||||||
|
actionContext = actionContext,
|
||||||
|
isPartial = isPartial,
|
||||||
|
result = viewResult,
|
||||||
|
viewName = viewName,
|
||||||
|
searchedLocations = searchedLocations,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,10 +2,12 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.ExceptionServices;
|
using System.Runtime.ExceptionServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Mvc.Controllers;
|
using Microsoft.AspNet.Mvc.Controllers;
|
||||||
|
using Microsoft.AspNet.Mvc.Diagnostics;
|
||||||
using Microsoft.AspNet.Mvc.Infrastructure;
|
using Microsoft.AspNet.Mvc.Infrastructure;
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
using Microsoft.AspNet.Mvc.ViewFeatures;
|
using Microsoft.AspNet.Mvc.ViewFeatures;
|
||||||
|
|
@ -16,10 +18,12 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
|
||||||
{
|
{
|
||||||
private readonly ITypeActivatorCache _typeActivatorCache;
|
private readonly ITypeActivatorCache _typeActivatorCache;
|
||||||
private readonly IViewComponentActivator _viewComponentActivator;
|
private readonly IViewComponentActivator _viewComponentActivator;
|
||||||
|
private readonly DiagnosticSource _diagnosticSource;
|
||||||
|
|
||||||
public DefaultViewComponentInvoker(
|
public DefaultViewComponentInvoker(
|
||||||
ITypeActivatorCache typeActivatorCache,
|
ITypeActivatorCache typeActivatorCache,
|
||||||
IViewComponentActivator viewComponentActivator)
|
IViewComponentActivator viewComponentActivator,
|
||||||
|
DiagnosticSource diagnosticSource)
|
||||||
{
|
{
|
||||||
if (typeActivatorCache == null)
|
if (typeActivatorCache == null)
|
||||||
{
|
{
|
||||||
|
|
@ -31,8 +35,14 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
|
||||||
throw new ArgumentNullException(nameof(viewComponentActivator));
|
throw new ArgumentNullException(nameof(viewComponentActivator));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (diagnosticSource == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(diagnosticSource));
|
||||||
|
}
|
||||||
|
|
||||||
_typeActivatorCache = typeActivatorCache;
|
_typeActivatorCache = typeActivatorCache;
|
||||||
_viewComponentActivator = viewComponentActivator;
|
_viewComponentActivator = viewComponentActivator;
|
||||||
|
_diagnosticSource = diagnosticSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Invoke(ViewComponentContext context)
|
public void Invoke(ViewComponentContext context)
|
||||||
|
|
@ -52,6 +62,7 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = InvokeSyncCore(method, context);
|
var result = InvokeSyncCore(method, context);
|
||||||
|
|
||||||
result.Execute(context);
|
result.Execute(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,9 +135,15 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
|
||||||
|
|
||||||
var component = CreateComponent(context);
|
var component = CreateComponent(context);
|
||||||
|
|
||||||
|
_diagnosticSource.BeforeViewComponent(context, component);
|
||||||
|
|
||||||
var result = await ControllerActionExecutor.ExecuteAsync(method, component, context.Arguments);
|
var result = await ControllerActionExecutor.ExecuteAsync(method, component, context.Arguments);
|
||||||
|
|
||||||
return CoerceToViewComponentResult(result);
|
var viewComponentResult = CoerceToViewComponentResult(result);
|
||||||
|
|
||||||
|
_diagnosticSource.AfterViewComponent(context, viewComponentResult, component);
|
||||||
|
|
||||||
|
return viewComponentResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IViewComponentResult InvokeSyncCore(MethodInfo method, ViewComponentContext context)
|
public IViewComponentResult InvokeSyncCore(MethodInfo method, ViewComponentContext context)
|
||||||
|
|
@ -145,6 +162,8 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
|
||||||
|
|
||||||
object result = null;
|
object result = null;
|
||||||
|
|
||||||
|
_diagnosticSource.BeforeViewComponent(context, component);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
result = method.Invoke(component, context.Arguments);
|
result = method.Invoke(component, context.Arguments);
|
||||||
|
|
@ -156,7 +175,11 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
|
||||||
exceptionInfo.Throw();
|
exceptionInfo.Throw();
|
||||||
}
|
}
|
||||||
|
|
||||||
return CoerceToViewComponentResult(result);
|
var viewComponentResult = CoerceToViewComponentResult(result);
|
||||||
|
|
||||||
|
_diagnosticSource.AfterViewComponent(context, viewComponentResult, component);
|
||||||
|
|
||||||
|
return viewComponentResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IViewComponentResult CoerceToViewComponentResult(object value)
|
private static IViewComponentResult CoerceToViewComponentResult(object value)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using Microsoft.AspNet.Mvc.Infrastructure;
|
using Microsoft.AspNet.Mvc.Infrastructure;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ViewComponents
|
namespace Microsoft.AspNet.Mvc.ViewComponents
|
||||||
|
|
@ -10,13 +11,16 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
|
||||||
{
|
{
|
||||||
private readonly ITypeActivatorCache _typeActivatorCache;
|
private readonly ITypeActivatorCache _typeActivatorCache;
|
||||||
private readonly IViewComponentActivator _viewComponentActivator;
|
private readonly IViewComponentActivator _viewComponentActivator;
|
||||||
|
private readonly DiagnosticSource _diagnosticSource;
|
||||||
|
|
||||||
public DefaultViewComponentInvokerFactory(
|
public DefaultViewComponentInvokerFactory(
|
||||||
ITypeActivatorCache typeActivatorCache,
|
ITypeActivatorCache typeActivatorCache,
|
||||||
IViewComponentActivator viewComponentActivator)
|
IViewComponentActivator viewComponentActivator,
|
||||||
|
DiagnosticSource diagnosticSource)
|
||||||
{
|
{
|
||||||
_typeActivatorCache = typeActivatorCache;
|
_typeActivatorCache = typeActivatorCache;
|
||||||
_viewComponentActivator = viewComponentActivator;
|
_viewComponentActivator = viewComponentActivator;
|
||||||
|
_diagnosticSource = diagnosticSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -32,7 +36,8 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
|
||||||
|
|
||||||
return new DefaultViewComponentInvoker(
|
return new DefaultViewComponentInvoker(
|
||||||
_typeActivatorCache,
|
_typeActivatorCache,
|
||||||
_viewComponentActivator);
|
_viewComponentActivator,
|
||||||
|
_diagnosticSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,10 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Mvc.Diagnostics;
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
using Microsoft.AspNet.Mvc.ViewEngines;
|
using Microsoft.AspNet.Mvc.ViewEngines;
|
||||||
using Microsoft.AspNet.Mvc.ViewFeatures;
|
using Microsoft.AspNet.Mvc.ViewFeatures;
|
||||||
|
|
@ -20,6 +22,8 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
|
||||||
private const string ViewPathFormat = "Components/{0}/{1}";
|
private const string ViewPathFormat = "Components/{0}/{1}";
|
||||||
private const string DefaultViewName = "Default";
|
private const string DefaultViewName = "Default";
|
||||||
|
|
||||||
|
private DiagnosticSource _diagnosticSource;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the view name.
|
/// Gets or sets the view name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -115,7 +119,16 @@ namespace Microsoft.AspNet.Mvc.ViewComponents
|
||||||
|
|
||||||
using (view as IDisposable)
|
using (view as IDisposable)
|
||||||
{
|
{
|
||||||
|
if (_diagnosticSource == null)
|
||||||
|
{
|
||||||
|
_diagnosticSource = context.ViewContext.HttpContext.RequestServices.GetRequiredService<DiagnosticSource>();
|
||||||
|
}
|
||||||
|
|
||||||
|
_diagnosticSource.ViewComponentBeforeViewExecute(context, view);
|
||||||
|
|
||||||
await view.RenderAsync(childViewContext);
|
await view.RenderAsync(childViewContext);
|
||||||
|
|
||||||
|
_diagnosticSource.ViewComponentAfterViewExecute(context, view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Mvc.Diagnostics;
|
||||||
using Microsoft.AspNet.Mvc.Infrastructure;
|
using Microsoft.AspNet.Mvc.Infrastructure;
|
||||||
using Microsoft.AspNet.Mvc.Logging;
|
using Microsoft.AspNet.Mvc.Logging;
|
||||||
using Microsoft.AspNet.Mvc.ViewEngines;
|
using Microsoft.AspNet.Mvc.ViewEngines;
|
||||||
|
|
@ -70,37 +71,13 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
||||||
var result = viewEngine.FindPartialView(actionContext, viewName);
|
var result = viewEngine.FindPartialView(actionContext, viewName);
|
||||||
if (result.Success)
|
if (result.Success)
|
||||||
{
|
{
|
||||||
if (DiagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.ViewFound"))
|
DiagnosticSource.ViewFound(actionContext, true, viewResult, viewName, result.View);
|
||||||
{
|
|
||||||
DiagnosticSource.Write(
|
|
||||||
"Microsoft.AspNet.Mvc.ViewFound",
|
|
||||||
new
|
|
||||||
{
|
|
||||||
actionContext = actionContext,
|
|
||||||
isPartial = true,
|
|
||||||
result = viewResult,
|
|
||||||
viewName = viewName,
|
|
||||||
view = result.View,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.LogVerbose("The partial view '{PartialViewName}' was found.", viewName);
|
Logger.LogVerbose("The partial view '{PartialViewName}' was found.", viewName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (DiagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.ViewNotFound"))
|
DiagnosticSource.ViewNotFound(actionContext, true, viewResult, viewName, result.SearchedLocations);
|
||||||
{
|
|
||||||
DiagnosticSource.Write(
|
|
||||||
"Microsoft.AspNet.Mvc.ViewNotFound",
|
|
||||||
new
|
|
||||||
{
|
|
||||||
actionContext = actionContext,
|
|
||||||
isPartial = true,
|
|
||||||
result = viewResult,
|
|
||||||
viewName = viewName,
|
|
||||||
searchedLocations = result.SearchedLocations
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.LogError(
|
Logger.LogError(
|
||||||
"The partial view '{PartialViewName}' was not found. Searched locations: {SearchedViewLocations}",
|
"The partial view '{PartialViewName}' was not found. Searched locations: {SearchedViewLocations}",
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Mvc.Diagnostics;
|
||||||
using Microsoft.AspNet.Mvc.Infrastructure;
|
using Microsoft.AspNet.Mvc.Infrastructure;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
|
|
@ -162,21 +163,11 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures
|
||||||
writer,
|
writer,
|
||||||
ViewOptions.HtmlHelperOptions);
|
ViewOptions.HtmlHelperOptions);
|
||||||
|
|
||||||
if (DiagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.BeforeView"))
|
DiagnosticSource.BeforeView(view, viewContext);
|
||||||
{
|
|
||||||
DiagnosticSource.Write(
|
|
||||||
"Microsoft.AspNet.Mvc.BeforeView",
|
|
||||||
new { view = view, viewContext = viewContext, });
|
|
||||||
}
|
|
||||||
|
|
||||||
await view.RenderAsync(viewContext);
|
await view.RenderAsync(viewContext);
|
||||||
|
|
||||||
if (DiagnosticSource.IsEnabled("Microsoft.AspNet.Mvc.AfterView"))
|
DiagnosticSource.AfterView(view, viewContext);
|
||||||
{
|
|
||||||
DiagnosticSource.Write(
|
|
||||||
"Microsoft.AspNet.Mvc.AfterView",
|
|
||||||
new { view = view, viewContext = viewContext, });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perf: Invoke FlushAsync to ensure any buffered content is asynchronously written to the underlying
|
// Perf: Invoke FlushAsync to ensure any buffered content is asynchronously written to the underlying
|
||||||
// response asynchronously. In the absence of this line, the buffer gets synchronously written to the
|
// response asynchronously. In the absence of this line, the buffer gets synchronously written to the
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
{
|
||||||
|
public interface IProxyViewComponentContext
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
{
|
||||||
|
public interface IProxyViewComponentResult
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -220,5 +220,109 @@ namespace Microsoft.AspNet.Mvc
|
||||||
ViewContext = viewContext,
|
ViewContext = viewContext,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class OnBeforeViewComponentEventData
|
||||||
|
{
|
||||||
|
public IProxyActionDescriptor ActionDescriptor { get; set; }
|
||||||
|
|
||||||
|
public IProxyViewComponentContext ViewComponentContext { get; set; }
|
||||||
|
|
||||||
|
public object ViewComponent { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnBeforeViewComponentEventData BeforeViewComponent { get; set; }
|
||||||
|
|
||||||
|
[DiagnosticName("Microsoft.AspNet.Mvc.BeforeViewComponent")]
|
||||||
|
public virtual void OnBeforeViewComponent(
|
||||||
|
IProxyActionDescriptor actionDescriptor,
|
||||||
|
IProxyViewComponentContext viewComponentContext,
|
||||||
|
object viewComponent)
|
||||||
|
{
|
||||||
|
BeforeViewComponent = new OnBeforeViewComponentEventData()
|
||||||
|
{
|
||||||
|
ActionDescriptor = actionDescriptor,
|
||||||
|
ViewComponentContext = viewComponentContext,
|
||||||
|
ViewComponent = viewComponent
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OnAfterViewComponentEventData
|
||||||
|
{
|
||||||
|
public IProxyActionDescriptor ActionDescriptor { get; set; }
|
||||||
|
|
||||||
|
public IProxyViewComponentContext ViewComponentContext { get; set; }
|
||||||
|
|
||||||
|
public IProxyViewComponentResult ViewComponentResult { get; set; }
|
||||||
|
|
||||||
|
public object ViewComponent { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnAfterViewComponentEventData AfterViewComponent { get; set; }
|
||||||
|
|
||||||
|
[DiagnosticName("Microsoft.AspNet.Mvc.AfterViewComponent")]
|
||||||
|
public virtual void OnAfterViewComponent(
|
||||||
|
IProxyActionDescriptor actionDescriptor,
|
||||||
|
IProxyViewComponentContext viewComponentContext,
|
||||||
|
IProxyViewComponentResult viewComponentResult,
|
||||||
|
object viewComponent)
|
||||||
|
{
|
||||||
|
AfterViewComponent = new OnAfterViewComponentEventData()
|
||||||
|
{
|
||||||
|
ActionDescriptor = actionDescriptor,
|
||||||
|
ViewComponentContext = viewComponentContext,
|
||||||
|
ViewComponentResult = viewComponentResult,
|
||||||
|
ViewComponent = viewComponent
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OnViewComponentBeforeViewExecuteEventData
|
||||||
|
{
|
||||||
|
public IProxyActionDescriptor ActionDescriptor { get; set; }
|
||||||
|
|
||||||
|
public IProxyViewComponentContext ViewComponentContext { get; set; }
|
||||||
|
|
||||||
|
public IProxyView View { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnViewComponentBeforeViewExecuteEventData ViewComponentBeforeViewExecute { get; set; }
|
||||||
|
|
||||||
|
[DiagnosticName("Microsoft.AspNet.Mvc.ViewComponentBeforeViewExecute")]
|
||||||
|
public virtual void OnViewComponentBeforeViewExecute(
|
||||||
|
IProxyActionDescriptor actionDescriptor,
|
||||||
|
IProxyViewComponentContext viewComponentContext,
|
||||||
|
IProxyView view)
|
||||||
|
{
|
||||||
|
ViewComponentBeforeViewExecute = new OnViewComponentBeforeViewExecuteEventData()
|
||||||
|
{
|
||||||
|
ActionDescriptor = actionDescriptor,
|
||||||
|
ViewComponentContext = viewComponentContext,
|
||||||
|
View = view
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OnViewComponentAfterViewExecuteEventData
|
||||||
|
{
|
||||||
|
public IProxyActionDescriptor ActionDescriptor { get; set; }
|
||||||
|
|
||||||
|
public IProxyViewComponentContext ViewComponentContext { get; set; }
|
||||||
|
|
||||||
|
public IProxyView View { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnViewComponentAfterViewExecuteEventData ViewComponentAfterViewExecute { get; set; }
|
||||||
|
|
||||||
|
[DiagnosticName("Microsoft.AspNet.Mvc.ViewComponentAfterViewExecute")]
|
||||||
|
public virtual void OnViewComponentAfterViewExecute(
|
||||||
|
IProxyActionDescriptor actionDescriptor,
|
||||||
|
IProxyViewComponentContext viewComponentContext,
|
||||||
|
IProxyView view)
|
||||||
|
{
|
||||||
|
ViewComponentAfterViewExecute = new OnViewComponentAfterViewExecuteEventData()
|
||||||
|
{
|
||||||
|
ActionDescriptor = actionDescriptor,
|
||||||
|
ViewComponentContext = viewComponentContext,
|
||||||
|
View = view
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -103,7 +104,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
var expected = $"A view component named '{typeof(TextViewComponent).FullName}' could not be found.";
|
var expected = $"A view component named '{typeof(TextViewComponent).FullName}' could not be found.";
|
||||||
|
|
||||||
var actionContext = CreateActionContext();
|
var actionContext = CreateActionContext();
|
||||||
var services = CreateServices(actionContext.HttpContext);
|
var services = CreateServices(diagnosticListener: null, context: actionContext.HttpContext);
|
||||||
services.AddSingleton<IViewComponentSelector>();
|
services.AddSingleton<IViewComponentSelector>();
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -175,6 +176,44 @@ namespace Microsoft.AspNet.Mvc
|
||||||
Assert.Equal("Hello-Async, World!", body);
|
Assert.Equal("Hello-Async, World!", body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ExecuteResultAsync_ExecutesViewComponent_AndWritesDiagnosticSource()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var descriptor = new ViewComponentDescriptor()
|
||||||
|
{
|
||||||
|
FullName = "Full.Name.Text",
|
||||||
|
ShortName = "Text",
|
||||||
|
Type = typeof(TextViewComponent),
|
||||||
|
};
|
||||||
|
|
||||||
|
var adapter = new TestDiagnosticListener();
|
||||||
|
|
||||||
|
var actionContext = CreateActionContext(adapter, descriptor);
|
||||||
|
|
||||||
|
var viewComponentResult = new ViewComponentResult()
|
||||||
|
{
|
||||||
|
Arguments = new object[] { "World!" },
|
||||||
|
ViewComponentName = "Text",
|
||||||
|
TempData = _tempDataDictionary,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await viewComponentResult.ExecuteResultAsync(actionContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var body = ReadBody(actionContext.HttpContext.Response);
|
||||||
|
Assert.Equal("Hello, World!", body);
|
||||||
|
|
||||||
|
Assert.NotNull(adapter.BeforeViewComponent?.ActionDescriptor);
|
||||||
|
Assert.NotNull(adapter.BeforeViewComponent?.ViewComponentContext);
|
||||||
|
Assert.NotNull(adapter.BeforeViewComponent?.ViewComponent);
|
||||||
|
Assert.NotNull(adapter.AfterViewComponent?.ActionDescriptor);
|
||||||
|
Assert.NotNull(adapter.AfterViewComponent?.ViewComponentContext);
|
||||||
|
Assert.NotNull(adapter.AfterViewComponent?.ViewComponentResult);
|
||||||
|
Assert.NotNull(adapter.AfterViewComponent?.ViewComponent);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ExecuteResultAsync_ExecutesViewComponent_ByShortName()
|
public async Task ExecuteResultAsync_ExecutesViewComponent_ByShortName()
|
||||||
{
|
{
|
||||||
|
|
@ -413,12 +452,18 @@ namespace Microsoft.AspNet.Mvc
|
||||||
Assert.Equal(expectedContentType, actionContext.HttpContext.Response.ContentType);
|
Assert.Equal(expectedContentType, actionContext.HttpContext.Response.ContentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IServiceCollection CreateServices(HttpContext context, params ViewComponentDescriptor[] descriptors)
|
private IServiceCollection CreateServices(object diagnosticListener, HttpContext context, params ViewComponentDescriptor[] descriptors)
|
||||||
{
|
{
|
||||||
var httpContext = new HttpContextAccessor() { HttpContext = context };
|
var httpContext = new HttpContextAccessor() { HttpContext = context };
|
||||||
var tempDataProvider = new SessionStateTempDataProvider();
|
var tempDataProvider = new SessionStateTempDataProvider();
|
||||||
|
var diagnosticSource = new DiagnosticListener("Microsoft.AspNet");
|
||||||
|
if (diagnosticListener != null)
|
||||||
|
{
|
||||||
|
diagnosticSource.SubscribeWithAdapter(diagnosticListener);
|
||||||
|
}
|
||||||
|
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
|
services.AddInstance<DiagnosticSource>(diagnosticSource);
|
||||||
services.AddSingleton<IOptions<MvcViewOptions>, TestOptionsManager<MvcViewOptions>>();
|
services.AddSingleton<IOptions<MvcViewOptions>, TestOptionsManager<MvcViewOptions>>();
|
||||||
services.AddTransient<IViewComponentHelper, DefaultViewComponentHelper>();
|
services.AddTransient<IViewComponentHelper, DefaultViewComponentHelper>();
|
||||||
services.AddSingleton<IViewComponentSelector, DefaultViewComponentSelector>();
|
services.AddSingleton<IViewComponentSelector, DefaultViewComponentSelector>();
|
||||||
|
|
@ -435,10 +480,10 @@ namespace Microsoft.AspNet.Mvc
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpContext CreateHttpContext(params ViewComponentDescriptor[] descriptors)
|
private HttpContext CreateHttpContext(object diagnosticListener, params ViewComponentDescriptor[] descriptors)
|
||||||
{
|
{
|
||||||
var httpContext = new DefaultHttpContext();
|
var httpContext = new DefaultHttpContext();
|
||||||
var services = CreateServices(httpContext, descriptors);
|
var services = CreateServices(diagnosticListener, httpContext, descriptors);
|
||||||
|
|
||||||
httpContext.Response.Body = new MemoryStream();
|
httpContext.Response.Body = new MemoryStream();
|
||||||
httpContext.RequestServices = services.BuildServiceProvider();
|
httpContext.RequestServices = services.BuildServiceProvider();
|
||||||
|
|
@ -446,11 +491,17 @@ namespace Microsoft.AspNet.Mvc
|
||||||
return httpContext;
|
return httpContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ActionContext CreateActionContext(object diagnosticListener, params ViewComponentDescriptor[] descriptors)
|
||||||
|
{
|
||||||
|
return new ActionContext(CreateHttpContext(diagnosticListener, descriptors), new RouteData(), new ActionDescriptor());
|
||||||
|
}
|
||||||
|
|
||||||
private ActionContext CreateActionContext(params ViewComponentDescriptor[] descriptors)
|
private ActionContext CreateActionContext(params ViewComponentDescriptor[] descriptors)
|
||||||
{
|
{
|
||||||
return new ActionContext(CreateHttpContext(descriptors), new RouteData(), new ActionDescriptor());
|
return CreateActionContext(null, descriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class FixedSetViewComponentDescriptorProvider : IViewComponentDescriptorProvider
|
private class FixedSetViewComponentDescriptorProvider : IViewComponentDescriptorProvider
|
||||||
{
|
{
|
||||||
private readonly ViewComponentDescriptor[] _descriptors;
|
private readonly ViewComponentDescriptor[] _descriptors;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#if MOCK_SUPPORT
|
#if MOCK_SUPPORT
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http.Internal;
|
using Microsoft.AspNet.Http.Internal;
|
||||||
|
|
@ -91,6 +92,48 @@ namespace Microsoft.AspNet.Mvc
|
||||||
view.Verify();
|
view.Verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Execute_ResolvesView_AndWritesDiagnosticSource()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var view = new Mock<IView>(MockBehavior.Strict);
|
||||||
|
view.Setup(v => v.RenderAsync(It.IsAny<ViewContext>()))
|
||||||
|
.Returns(Task.FromResult(result: true))
|
||||||
|
.Verifiable();
|
||||||
|
|
||||||
|
var viewEngine = new Mock<IViewEngine>(MockBehavior.Strict);
|
||||||
|
viewEngine.Setup(e => e.FindPartialView(It.IsAny<ActionContext>(), It.IsAny<string>()))
|
||||||
|
.Returns(ViewEngineResult.Found("Default", view.Object))
|
||||||
|
.Verifiable();
|
||||||
|
|
||||||
|
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
|
||||||
|
|
||||||
|
var result = new ViewViewComponentResult
|
||||||
|
{
|
||||||
|
ViewEngine = viewEngine.Object,
|
||||||
|
ViewData = viewData,
|
||||||
|
TempData = _tempDataDictionary,
|
||||||
|
};
|
||||||
|
|
||||||
|
var adapter = new TestDiagnosticListener();
|
||||||
|
|
||||||
|
var viewComponentContext = GetViewComponentContext(view.Object, viewData, adapter);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
result.Execute(viewComponentContext);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
viewEngine.Verify();
|
||||||
|
view.Verify();
|
||||||
|
|
||||||
|
Assert.NotNull(adapter.ViewComponentBeforeViewExecute?.ActionDescriptor);
|
||||||
|
Assert.NotNull(adapter.ViewComponentBeforeViewExecute?.ViewComponentContext);
|
||||||
|
Assert.NotNull(adapter.ViewComponentBeforeViewExecute?.View);
|
||||||
|
Assert.NotNull(adapter.ViewComponentAfterViewExecute?.ActionDescriptor);
|
||||||
|
Assert.NotNull(adapter.ViewComponentAfterViewExecute?.ViewComponentContext);
|
||||||
|
Assert.NotNull(adapter.ViewComponentAfterViewExecute?.View);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Execute_ThrowsIfPartialViewCannotBeFound()
|
public void Execute_ThrowsIfPartialViewCannotBeFound()
|
||||||
{
|
{
|
||||||
|
|
@ -204,6 +247,8 @@ namespace Microsoft.AspNet.Mvc
|
||||||
var serviceProvider = new Mock<IServiceProvider>();
|
var serviceProvider = new Mock<IServiceProvider>();
|
||||||
serviceProvider.Setup(p => p.GetService(typeof(ICompositeViewEngine)))
|
serviceProvider.Setup(p => p.GetService(typeof(ICompositeViewEngine)))
|
||||||
.Returns(viewEngine.Object);
|
.Returns(viewEngine.Object);
|
||||||
|
serviceProvider.Setup(p => p.GetService(typeof(DiagnosticSource)))
|
||||||
|
.Returns(new DiagnosticListener("Test"));
|
||||||
|
|
||||||
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
|
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
|
||||||
|
|
||||||
|
|
@ -345,9 +390,23 @@ namespace Microsoft.AspNet.Mvc
|
||||||
viewEngine.Verify();
|
viewEngine.Verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ViewComponentContext GetViewComponentContext(IView view, ViewDataDictionary viewData)
|
private static ViewComponentContext GetViewComponentContext(IView view, ViewDataDictionary viewData, object diagnosticListener = null)
|
||||||
{
|
{
|
||||||
var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
|
var diagnosticSource = new DiagnosticListener("Microsoft.AspNet");
|
||||||
|
if (diagnosticListener == null)
|
||||||
|
{
|
||||||
|
diagnosticListener = new TestDiagnosticListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
diagnosticSource.SubscribeWithAdapter(diagnosticListener);
|
||||||
|
|
||||||
|
var serviceProvider = new Mock<IServiceProvider>();
|
||||||
|
serviceProvider.Setup(s => s.GetService(typeof(DiagnosticSource))).Returns(diagnosticSource);
|
||||||
|
|
||||||
|
var httpContext = new DefaultHttpContext();
|
||||||
|
httpContext.RequestServices = serviceProvider.Object;
|
||||||
|
|
||||||
|
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
|
||||||
var viewContext = new ViewContext(
|
var viewContext = new ViewContext(
|
||||||
actionContext,
|
actionContext,
|
||||||
view,
|
view,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue