From b758a86a38d77bcf64c870aeb7db8371182f4024 Mon Sep 17 00:00:00 2001 From: Jass Bagga Date: Fri, 12 May 2017 14:15:29 -0700 Subject: [PATCH] Modify ViewComponent_CannotFindComponent error message (#6263) --- .../Properties/Resources.Designer.cs | 8 ++++---- .../Resources.resx | 2 +- .../ViewComponents/DefaultViewComponentHelper.cs | 11 +++++++++-- .../ViewComponents/ViewComponentConventions.cs | 2 +- .../ViewComponentResultTest.cs | 10 ++++++++-- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Properties/Resources.Designer.cs index 19c9606e96..976283c6c0 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Properties/Resources.Designer.cs @@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_SyncMethod_ShouldReturnValue"), p0, p1); /// - /// A view component named '{0}' could not be found. + /// A view component named '{0}' could not be found. A view component must be a public non-abstract class, not contain any generic parameters, and either be decorated with '{1}' or have a class name ending with the '{2}' suffix. A view component must not be decorated with '{3}'. /// internal static string ViewComponent_CannotFindComponent { @@ -75,10 +75,10 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures } /// - /// A view component named '{0}' could not be found. + /// A view component named '{0}' could not be found. A view component must be a public non-abstract class, not contain any generic parameters, and either be decorated with '{1}' or have a class name ending with the '{2}' suffix. A view component must not be decorated with '{3}'. /// - internal static string FormatViewComponent_CannotFindComponent(object p0) - => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_CannotFindComponent"), p0); + internal static string FormatViewComponent_CannotFindComponent(object p0, object p1, object p2, object p3) + => string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_CannotFindComponent"), p0, p1, p2, p3); /// /// An invoker could not be created for the view component '{0}'. diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Resources.resx b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Resources.resx index 87c26e3d07..baa6c7a29b 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Resources.resx +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Resources.resx @@ -131,7 +131,7 @@ Method '{0}' of view component '{1}' should be declared to return a value. - A view component named '{0}' could not be found. + A view component named '{0}' could not be found. A view component must be a public non-abstract class, not contain any generic parameters, and either be decorated with '{1}' or have a class name ending with the '{2}' suffix. A view component must not be decorated with '{3}'. An invoker could not be created for the view component '{0}'. diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponents/DefaultViewComponentHelper.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponents/DefaultViewComponentHelper.cs index 19221c2916..e55e5443a4 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponents/DefaultViewComponentHelper.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponents/DefaultViewComponentHelper.cs @@ -98,7 +98,11 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents var descriptor = _selector.SelectComponent(name); if (descriptor == null) { - throw new InvalidOperationException(Resources.FormatViewComponent_CannotFindComponent(name)); + throw new InvalidOperationException(Resources.FormatViewComponent_CannotFindComponent( + name, + nameof(ViewComponentAttribute), + ViewComponentConventions.ViewComponentSuffix, + nameof(NonViewComponentAttribute))); } return InvokeCoreAsync(descriptor, arguments); @@ -129,7 +133,10 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents } throw new InvalidOperationException(Resources.FormatViewComponent_CannotFindComponent( - componentType.FullName)); + componentType.FullName, + nameof(ViewComponentAttribute), + ViewComponentConventions.ViewComponentSuffix, + nameof(NonViewComponentAttribute))); } // Internal for testing diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponents/ViewComponentConventions.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponents/ViewComponentConventions.cs index d8e4ce1a61..8ad8797556 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponents/ViewComponentConventions.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/ViewComponents/ViewComponentConventions.cs @@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewComponents { public static class ViewComponentConventions { - private const string ViewComponentSuffix = "ViewComponent"; + public static readonly string ViewComponentSuffix = "ViewComponent"; public static string GetComponentName(TypeInfo componentType) { diff --git a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/ViewComponentResultTest.cs b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/ViewComponentResultTest.cs index cf17cfc2ee..f7da43fc3b 100644 --- a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/ViewComponentResultTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/ViewComponentResultTest.cs @@ -105,7 +105,10 @@ namespace Microsoft.AspNetCore.Mvc public async Task ExecuteResultAsync_Throws_IfViewComponentCouldNotBeFound_ByName() { // Arrange - var expected = "A view component named 'Text' could not be found."; + var expected = "A view component named 'Text' could not be found. A view component must be " + + "a public non-abstract class, not contain any generic parameters, and either be decorated " + + "with 'ViewComponentAttribute' or have a class name ending with the 'ViewComponent' suffix. " + + "A view component must not be decorated with 'NonViewComponentAttribute'."; var actionContext = CreateActionContext(); @@ -125,7 +128,10 @@ namespace Microsoft.AspNetCore.Mvc public async Task ExecuteResultAsync_Throws_IfViewComponentCouldNotBeFound_ByType() { // Arrange - 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. " + + "A view component must be a public non-abstract class, not contain any generic parameters, and either be decorated " + + "with 'ViewComponentAttribute' or have a class name ending with the 'ViewComponent' suffix. " + + "A view component must not be decorated with 'NonViewComponentAttribute'."; var actionContext = CreateActionContext(); var services = CreateServices(diagnosticListener: null, context: actionContext.HttpContext);