diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/PageBase.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/PageBase.cs index 12b88777e8..b23063eeb0 100644 --- a/src/Microsoft.AspNetCore.Mvc.RazorPages/PageBase.cs +++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/PageBase.cs @@ -149,7 +149,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages /// Creates a that produces a response. /// /// The created for the response. - [NonAction] public virtual BadRequestResult BadRequest() => new BadRequestResult(); @@ -158,7 +157,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages /// /// An error object to be returned to the client. /// The created for the response. - [NonAction] public virtual BadRequestObjectResult BadRequest(object error) => new BadRequestObjectResult(error); @@ -167,7 +165,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages /// /// The containing errors to be returned to the client. /// The created for the response. - [NonAction] public virtual BadRequestObjectResult BadRequest(ModelStateDictionary modelState) { if (modelState == null) @@ -1217,6 +1214,78 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages public virtual UnauthorizedResult Unauthorized() => new UnauthorizedResult(); + #region ViewComponentResult + /// + /// Creates a by specifying the name of a view component to render. + /// + /// + /// The view component name. Can be a view component + /// or + /// . + /// The created object for the response. + public virtual ViewComponentResult ViewComponent(string componentName) + { + return ViewComponent(componentName, arguments: null); + } + + /// + /// Creates a by specifying the of a view component to + /// render. + /// + /// The view component . + /// The created object for the response. + public virtual ViewComponentResult ViewComponent(Type componentType) + { + return ViewComponent(componentType, arguments: null); + } + + /// + /// Creates a by specifying the name of a view component to render. + /// + /// + /// The view component name. Can be a view component + /// or + /// . + /// + /// An with properties representing arguments to be passed to the invoked view component + /// method. Alternatively, an instance + /// containing the invocation arguments. + /// + /// The created object for the response. + public virtual ViewComponentResult ViewComponent(string componentName, object arguments) + { + return new ViewComponentResult + { + ViewComponentName = componentName, + Arguments = arguments, + ViewData = ViewContext.ViewData, + TempData = TempData + }; + } + + /// + /// Creates a by specifying the of a view component to + /// render. + /// + /// The view component . + /// + /// An with properties representing arguments to be passed to the invoked view component + /// method. Alternatively, an instance + /// containing the invocation arguments. + /// + /// The created object for the response. + public virtual ViewComponentResult ViewComponent(Type componentType, object arguments) + { + return new ViewComponentResult + { + ViewComponentType = componentType, + Arguments = arguments, + ViewData = ViewContext.ViewData, + TempData = TempData + }; + } + #endregion + /// /// Updates the specified instance using values from the 's current /// . diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/PageModel.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/PageModel.cs index ce5a76af27..526d0fad72 100644 --- a/src/Microsoft.AspNetCore.Mvc.RazorPages/PageModel.cs +++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/PageModel.cs @@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages } /// - /// Gets or sets used by . + /// Gets the . /// public ViewDataDictionary ViewData => PageContext?.ViewData; @@ -524,7 +524,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages /// Creates a that produces a response. /// /// The created for the response. - [NonAction] public virtual BadRequestResult BadRequest() => new BadRequestResult(); @@ -533,7 +532,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages /// /// An error object to be returned to the client. /// The created for the response. - [NonAction] public virtual BadRequestObjectResult BadRequest(object error) => new BadRequestObjectResult(error); @@ -542,7 +540,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages /// /// The containing errors to be returned to the client. /// The created for the response. - [NonAction] public virtual BadRequestObjectResult BadRequest(ModelStateDictionary modelState) { if (modelState == null) @@ -1617,6 +1614,78 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages public virtual UnauthorizedResult Unauthorized() => new UnauthorizedResult(); + #region ViewComponentResult + /// + /// Creates a by specifying the name of a view component to render. + /// + /// + /// The view component name. Can be a view component + /// or + /// . + /// The created object for the response. + public virtual ViewComponentResult ViewComponent(string componentName) + { + return ViewComponent(componentName, arguments: null); + } + + /// + /// Creates a by specifying the of a view component to + /// render. + /// + /// The view component . + /// The created object for the response. + public virtual ViewComponentResult ViewComponent(Type componentType) + { + return ViewComponent(componentType, arguments: null); + } + + /// + /// Creates a by specifying the name of a view component to render. + /// + /// + /// The view component name. Can be a view component + /// or + /// . + /// + /// An with properties representing arguments to be passed to the invoked view component + /// method. Alternatively, an instance + /// containing the invocation arguments. + /// + /// The created object for the response. + public virtual ViewComponentResult ViewComponent(string componentName, object arguments) + { + return new ViewComponentResult + { + ViewComponentName = componentName, + Arguments = arguments, + ViewData = ViewData, + TempData = TempData + }; + } + + /// + /// Creates a by specifying the of a view component to + /// render. + /// + /// The view component . + /// + /// An with properties representing arguments to be passed to the invoked view component + /// method. Alternatively, an instance + /// containing the invocation arguments. + /// + /// The created object for the response. + public virtual ViewComponentResult ViewComponent(Type componentType, object arguments) + { + return new ViewComponentResult + { + ViewComponentType = componentType, + Arguments = arguments, + ViewData = ViewData, + TempData = TempData + }; + } + #endregion + /// /// Validates the specified instance. /// @@ -1657,7 +1726,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages return ModelState.IsValid; } -#region IAsyncPageFilter \ IPageFilter + #region IAsyncPageFilter \ IPageFilter /// /// Called after a handler method has been selected, but before model binding occurs. /// @@ -1724,6 +1793,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages OnPageHandlerExecuted(await next()); } } -#endregion + #endregion } } diff --git a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageModelTest.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageModelTest.cs index 6d0913d394..b73abd57b9 100644 --- a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageModelTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageModelTest.cs @@ -329,80 +329,80 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages [InlineData("")] [InlineData(null)] [InlineData("SampleController")] - public void RedirectToAction_WithParameterActionAndControllerName_SetsEqualNames(string pageModelName) + public void RedirectToAction_WithParameterActionAndControllerName_SetsEqualNames(string controllerName) { // Arrange var pageModel = new TestPageModel(); // Act - var resultTemporary = pageModel.RedirectToAction("SampleAction", pageModelName); + var resultTemporary = pageModel.RedirectToAction("SampleAction", controllerName); // Assert Assert.IsType(resultTemporary); Assert.False(resultTemporary.PreserveMethod); Assert.False(resultTemporary.Permanent); Assert.Equal("SampleAction", resultTemporary.ActionName); - Assert.Equal(pageModelName, resultTemporary.ControllerName); + Assert.Equal(controllerName, resultTemporary.ControllerName); } [Theory] [InlineData("")] [InlineData(null)] [InlineData("SampleController")] - public void RedirectToActionPreserveMethod_WithParameterActionAndControllerName_SetsEqualNames(string pageModelName) + public void RedirectToActionPreserveMethod_WithParameterActionAndControllerName_SetsEqualNames(string controllerName) { // Arrange var pageModel = new TestPageModel(); // Act - var resultTemporary = pageModel.RedirectToActionPreserveMethod(actionName: "SampleAction", controllerName: pageModelName); + var resultTemporary = pageModel.RedirectToActionPreserveMethod(actionName: "SampleAction", controllerName: controllerName); // Assert Assert.IsType(resultTemporary); Assert.True(resultTemporary.PreserveMethod); Assert.False(resultTemporary.Permanent); Assert.Equal("SampleAction", resultTemporary.ActionName); - Assert.Equal(pageModelName, resultTemporary.ControllerName); + Assert.Equal(controllerName, resultTemporary.ControllerName); } [Theory] [InlineData("")] [InlineData(null)] [InlineData("SampleController")] - public void RedirectToActionPermanent_WithParameterActionAndControllerName_SetsEqualNames(string pageModelName) + public void RedirectToActionPermanent_WithParameterActionAndControllerName_SetsEqualNames(string controllerName) { // Arrange var pageModel = new TestPageModel(); // Act - var resultPermanent = pageModel.RedirectToActionPermanent("SampleAction", pageModelName); + var resultPermanent = pageModel.RedirectToActionPermanent("SampleAction", controllerName); // Assert Assert.IsType(resultPermanent); Assert.False(resultPermanent.PreserveMethod); Assert.True(resultPermanent.Permanent); Assert.Equal("SampleAction", resultPermanent.ActionName); - Assert.Equal(pageModelName, resultPermanent.ControllerName); + Assert.Equal(controllerName, resultPermanent.ControllerName); } [Theory] [InlineData("")] [InlineData(null)] [InlineData("SampleController")] - public void RedirectToActionPermanentPreserveMethod_WithParameterActionAndControllerName_SetsEqualNames(string pageModelName) + public void RedirectToActionPermanentPreserveMethod_WithParameterActionAndControllerName_SetsEqualNames(string controllerName) { // Arrange var pageModel = new TestPageModel(); // Act - var resultPermanent = pageModel.RedirectToActionPermanentPreserveMethod(actionName: "SampleAction", controllerName: pageModelName); + var resultPermanent = pageModel.RedirectToActionPermanentPreserveMethod(actionName: "SampleAction", controllerName: controllerName); // Assert Assert.IsType(resultPermanent); Assert.True(resultPermanent.PreserveMethod); Assert.True(resultPermanent.Permanent); Assert.Equal("SampleAction", resultPermanent.ActionName); - Assert.Equal(pageModelName, resultPermanent.ControllerName); + Assert.Equal(controllerName, resultPermanent.ControllerName); } [Theory] @@ -1895,6 +1895,67 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages testPageModel.Verify(); } + [Fact] + public void ViewComponent_WithName() + { + // Arrange + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()); + var pageModel = new TestPageModel + { + PageContext = new PageContext + { + ViewData = viewData, + }, + }; + + // Act + var result = pageModel.ViewComponent("TagCloud"); + + // Assert + Assert.NotNull(result); + Assert.Equal("TagCloud", result.ViewComponentName); + Assert.Same(viewData, result.ViewData); + } + + [Fact] + public void ViewComponent_WithType() + { + // Arrange + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()); + var pageModel = new TestPageModel + { + PageContext = new PageContext + { + ViewData = viewData, + }, + }; + + // Act + var result = pageModel.ViewComponent(typeof(Guid)); + + // Assert + Assert.NotNull(result); + Assert.Equal(typeof(Guid), result.ViewComponentType); + Assert.Same(viewData, result.ViewData); + } + + [Fact] + public void ViewComponent_WithArguments() + { + // Arrange + var pageModel = new TestPageModel(); + var arguments = new { Arg1 = "Hi", Arg2 = "There" }; + + // Act + var result = pageModel.ViewComponent(typeof(Guid), arguments); + + // Assert + Assert.NotNull(result); + + Assert.Equal(typeof(Guid), result.ViewComponentType); + Assert.Same(arguments, result.Arguments); + } + private class ContentPageModel : PageModel { public IActionResult Content_WithNoEncoding() diff --git a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageTest.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageTest.cs index aaefccfcc9..f253c06d43 100644 --- a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/PageTest.cs @@ -1698,6 +1698,76 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages Assert.Equal(statusCode, result.StatusCode); } + [Fact] + public void ViewComponent_WithName() + { + // Arrange + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()); + var page = new TestPage + { + ViewContext = new ViewContext + { + ViewData = viewData, + }, + }; + + // Act + var result = page.ViewComponent("TagCloud"); + + // Assert + Assert.NotNull(result); + Assert.Equal("TagCloud", result.ViewComponentName); + Assert.Same(viewData, result.ViewData); + } + + [Fact] + public void ViewComponent_WithType() + { + // Arrange + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()); + var page = new TestPage + { + ViewContext = new ViewContext + { + ViewData = viewData, + }, + }; + + // Act + var result = page.ViewComponent(typeof(Guid)); + + // Assert + Assert.NotNull(result); + Assert.Equal(typeof(Guid), result.ViewComponentType); + Assert.Same(viewData, result.ViewData); + } + + [Fact] + public void ViewComponent_WithArguments() + { + // Arrange + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()); + var page = new TestPage + { + ViewContext = new ViewContext + { + ViewData = viewData, + }, + }; + + var arguments = new { Arg1 = "Hi", Arg2 = "There" }; + + // Act + var result = page.ViewComponent(typeof(Guid), arguments); + + // Assert + Assert.NotNull(result); + + Assert.Equal(typeof(Guid), result.ViewComponentType); + Assert.Same(arguments, result.Arguments); + Assert.Same(viewData, result.ViewData); + } + public static IEnumerable RedirectTestData { get