Add ViewComponentResult helper methods to Page \ PageModel

Fixes #7051
This commit is contained in:
Pranav K 2018-02-05 17:44:20 -08:00
parent f52c9c0f97
commit 26454fb1da
4 changed files with 290 additions and 21 deletions

View File

@ -149,7 +149,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// Creates a <see cref="BadRequestResult"/> that produces a <see cref="StatusCodes.Status400BadRequest"/> response.
/// </summary>
/// <returns>The created <see cref="BadRequestResult"/> for the response.</returns>
[NonAction]
public virtual BadRequestResult BadRequest()
=> new BadRequestResult();
@ -158,7 +157,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// </summary>
/// <param name="error">An error object to be returned to the client.</param>
/// <returns>The created <see cref="BadRequestObjectResult"/> for the response.</returns>
[NonAction]
public virtual BadRequestObjectResult BadRequest(object error)
=> new BadRequestObjectResult(error);
@ -167,7 +165,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// </summary>
/// <param name="modelState">The <see cref="ModelStateDictionary" /> containing errors to be returned to the client.</param>
/// <returns>The created <see cref="BadRequestObjectResult"/> for the response.</returns>
[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
/// <summary>
/// Creates a <see cref="ViewComponentResult"/> by specifying the name of a view component to render.
/// </summary>
/// <param name="componentName">
/// The view component name. Can be a view component
/// <see cref="ViewComponents.ViewComponentDescriptor.ShortName"/> or
/// <see cref="ViewComponents.ViewComponentDescriptor.FullName"/>.</param>
/// <returns>The created <see cref="ViewComponentResult"/> object for the response.</returns>
public virtual ViewComponentResult ViewComponent(string componentName)
{
return ViewComponent(componentName, arguments: null);
}
/// <summary>
/// Creates a <see cref="ViewComponentResult"/> by specifying the <see cref="Type"/> of a view component to
/// render.
/// </summary>
/// <param name="componentType">The view component <see cref="Type"/>.</param>
/// <returns>The created <see cref="ViewComponentResult"/> object for the response.</returns>
public virtual ViewComponentResult ViewComponent(Type componentType)
{
return ViewComponent(componentType, arguments: null);
}
/// <summary>
/// Creates a <see cref="ViewComponentResult"/> by specifying the name of a view component to render.
/// </summary>
/// <param name="componentName">
/// The view component name. Can be a view component
/// <see cref="ViewComponents.ViewComponentDescriptor.ShortName"/> or
/// <see cref="ViewComponents.ViewComponentDescriptor.FullName"/>.</param>
/// <param name="arguments">
/// An <see cref="object"/> with properties representing arguments to be passed to the invoked view component
/// method. Alternatively, an <see cref="System.Collections.Generic.IDictionary{String, Object}"/> instance
/// containing the invocation arguments.
/// </param>
/// <returns>The created <see cref="ViewComponentResult"/> object for the response.</returns>
public virtual ViewComponentResult ViewComponent(string componentName, object arguments)
{
return new ViewComponentResult
{
ViewComponentName = componentName,
Arguments = arguments,
ViewData = ViewContext.ViewData,
TempData = TempData
};
}
/// <summary>
/// Creates a <see cref="ViewComponentResult"/> by specifying the <see cref="Type"/> of a view component to
/// render.
/// </summary>
/// <param name="componentType">The view component <see cref="Type"/>.</param>
/// <param name="arguments">
/// An <see cref="object"/> with properties representing arguments to be passed to the invoked view component
/// method. Alternatively, an <see cref="System.Collections.Generic.IDictionary{String, Object}"/> instance
/// containing the invocation arguments.
/// </param>
/// <returns>The created <see cref="ViewComponentResult"/> object for the response.</returns>
public virtual ViewComponentResult ViewComponent(Type componentType, object arguments)
{
return new ViewComponentResult
{
ViewComponentType = componentType,
Arguments = arguments,
ViewData = ViewContext.ViewData,
TempData = TempData
};
}
#endregion
/// <summary>
/// Updates the specified <paramref name="model"/> instance using values from the <see cref="RazorPages.Page"/>'s current
/// <see cref="IValueProvider"/>.

View File

@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
}
/// <summary>
/// Gets or sets <see cref="ViewDataDictionary"/> used by <see cref="PageResult"/>.
/// Gets the <see cref="ViewDataDictionary"/>.
/// </summary>
public ViewDataDictionary ViewData => PageContext?.ViewData;
@ -524,7 +524,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// Creates a <see cref="BadRequestResult"/> that produces a <see cref="StatusCodes.Status400BadRequest"/> response.
/// </summary>
/// <returns>The created <see cref="BadRequestResult"/> for the response.</returns>
[NonAction]
public virtual BadRequestResult BadRequest()
=> new BadRequestResult();
@ -533,7 +532,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// </summary>
/// <param name="error">An error object to be returned to the client.</param>
/// <returns>The created <see cref="BadRequestObjectResult"/> for the response.</returns>
[NonAction]
public virtual BadRequestObjectResult BadRequest(object error)
=> new BadRequestObjectResult(error);
@ -542,7 +540,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// </summary>
/// <param name="modelState">The <see cref="ModelStateDictionary" /> containing errors to be returned to the client.</param>
/// <returns>The created <see cref="BadRequestObjectResult"/> for the response.</returns>
[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
/// <summary>
/// Creates a <see cref="ViewComponentResult"/> by specifying the name of a view component to render.
/// </summary>
/// <param name="componentName">
/// The view component name. Can be a view component
/// <see cref="ViewComponents.ViewComponentDescriptor.ShortName"/> or
/// <see cref="ViewComponents.ViewComponentDescriptor.FullName"/>.</param>
/// <returns>The created <see cref="ViewComponentResult"/> object for the response.</returns>
public virtual ViewComponentResult ViewComponent(string componentName)
{
return ViewComponent(componentName, arguments: null);
}
/// <summary>
/// Creates a <see cref="ViewComponentResult"/> by specifying the <see cref="Type"/> of a view component to
/// render.
/// </summary>
/// <param name="componentType">The view component <see cref="Type"/>.</param>
/// <returns>The created <see cref="ViewComponentResult"/> object for the response.</returns>
public virtual ViewComponentResult ViewComponent(Type componentType)
{
return ViewComponent(componentType, arguments: null);
}
/// <summary>
/// Creates a <see cref="ViewComponentResult"/> by specifying the name of a view component to render.
/// </summary>
/// <param name="componentName">
/// The view component name. Can be a view component
/// <see cref="ViewComponents.ViewComponentDescriptor.ShortName"/> or
/// <see cref="ViewComponents.ViewComponentDescriptor.FullName"/>.</param>
/// <param name="arguments">
/// An <see cref="object"/> with properties representing arguments to be passed to the invoked view component
/// method. Alternatively, an <see cref="System.Collections.Generic.IDictionary{String, Object}"/> instance
/// containing the invocation arguments.
/// </param>
/// <returns>The created <see cref="ViewComponentResult"/> object for the response.</returns>
public virtual ViewComponentResult ViewComponent(string componentName, object arguments)
{
return new ViewComponentResult
{
ViewComponentName = componentName,
Arguments = arguments,
ViewData = ViewData,
TempData = TempData
};
}
/// <summary>
/// Creates a <see cref="ViewComponentResult"/> by specifying the <see cref="Type"/> of a view component to
/// render.
/// </summary>
/// <param name="componentType">The view component <see cref="Type"/>.</param>
/// <param name="arguments">
/// An <see cref="object"/> with properties representing arguments to be passed to the invoked view component
/// method. Alternatively, an <see cref="System.Collections.Generic.IDictionary{String, Object}"/> instance
/// containing the invocation arguments.
/// </param>
/// <returns>The created <see cref="ViewComponentResult"/> object for the response.</returns>
public virtual ViewComponentResult ViewComponent(Type componentType, object arguments)
{
return new ViewComponentResult
{
ViewComponentType = componentType,
Arguments = arguments,
ViewData = ViewData,
TempData = TempData
};
}
#endregion
/// <summary>
/// Validates the specified <paramref name="model"/> instance.
/// </summary>
@ -1657,7 +1726,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
return ModelState.IsValid;
}
#region IAsyncPageFilter \ IPageFilter
#region IAsyncPageFilter \ IPageFilter
/// <summary>
/// Called after a handler method has been selected, but before model binding occurs.
/// </summary>
@ -1724,6 +1793,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
OnPageHandlerExecuted(await next());
}
}
#endregion
#endregion
}
}

View File

@ -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<RedirectToActionResult>(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<RedirectToActionResult>(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<RedirectToActionResult>(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<RedirectToActionResult>(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()

View File

@ -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<object[]> RedirectTestData
{
get