Issue #1525 - Enhancements to ActionContext

- Adding a new constructor that takes ModelState.
 - Removing an extra constructor that's not needed
 - docs
 - test cleanup
This commit is contained in:
Ryan Nowak 2015-01-26 17:25:09 -08:00
parent 17aa21dc25
commit 08a578d01f
19 changed files with 111 additions and 67 deletions

View File

@ -1,42 +1,78 @@
// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Routing;
namespace Microsoft.AspNet.Mvc
{
/// <summary>
/// Context object for execution of action which has been selected as part of an HTTP request.
/// </summary>
public class ActionContext
{
/// <summary>
/// Creates a new <see cref="ActionContext"/>.
/// </summary>
/// <param name="actionContext">The <see cref="ActionContext"/> to copy.</param>
public ActionContext([NotNull] ActionContext actionContext)
: this(actionContext.HttpContext, actionContext.RouteData, actionContext.ActionDescriptor)
{
ModelState = actionContext.ModelState;
}
public ActionContext([NotNull] RouteContext routeContext, [NotNull] ActionDescriptor actionDescriptor)
: this(routeContext.HttpContext, routeContext.RouteData, actionDescriptor)
/// <summary>
/// Creates a new <see cref="ActionContext"/>.
/// </summary>
/// <param name="httpContext">The <see cref="Http.HttpContext"/> for the current request.</param>
/// <param name="routeData">The <see cref="AspNet.Routing.RouteData"/> for the current request.</param>
/// <param name="actionDescriptor">The <see cref="Mvc.ActionDescriptor"/> for the selected action.</param>
public ActionContext(
[NotNull] HttpContext httpContext,
[NotNull] RouteData routeData,
[NotNull] ActionDescriptor actionDescriptor)
: this(httpContext, routeData, actionDescriptor, new ModelStateDictionary())
{
}
public ActionContext([NotNull] HttpContext httpContext,
/// <summary>
/// Creates a new <see cref="ActionContext"/>.
/// </summary>
/// <param name="httpContext">The <see cref="Http.HttpContext"/> for the current request.</param>
/// <param name="routeData">The <see cref="AspNet.Routing.RouteData"/> for the current request.</param>
/// <param name="actionDescriptor">The <see cref="Mvc.ActionDescriptor"/> for the selected action.</param>
/// <param name="modelState">The <see cref="ModelStateDictionary"/>.</param>
public ActionContext(
[NotNull] HttpContext httpContext,
[NotNull] RouteData routeData,
[NotNull] ActionDescriptor actionDescriptor)
[NotNull] ActionDescriptor actionDescriptor,
[NotNull] ModelStateDictionary modelState)
{
HttpContext = httpContext;
RouteData = routeData;
ActionDescriptor = actionDescriptor;
ModelState = new ModelStateDictionary();
ModelState = modelState;
}
public HttpContext HttpContext { get; private set; }
/// <summary>
/// Gets the <see cref="Mvc.ActionDescriptor"/> for the selected action.
/// </summary>
public ActionDescriptor ActionDescriptor { get; }
public RouteData RouteData { get; private set; }
/// <summary>
/// Gets the <see cref="Http.HttpContext"/> for the current request.
/// </summary>
public HttpContext HttpContext { get; }
public ModelStateDictionary ModelState { get; private set; }
/// <summary>
/// Gets the <see cref="ModelStateDictionary"/>.
/// </summary>
public ModelStateDictionary ModelState { get; }
public ActionDescriptor ActionDescriptor { get; private set; }
/// <summary>
/// Gets the <see cref="AspNet.Routing.RouteData"/> for the current request.
/// </summary>
public RouteData RouteData { get; }
}
}

View File

@ -2027,9 +2027,8 @@ namespace Microsoft.AspNet.Mvc
var context = new Mock<HttpContext>();
context.SetupGet(c => c.Items)
.Returns(new Dictionary<object, object>());
var routeContext = new RouteContext(context.Object);
var actionContext = new ActionContext(routeContext, actionDescriptor);
var actionContext = new ActionContext(context.Object, new RouteData(), actionDescriptor);
var controllerFactory = new Mock<IControllerFactory>();
controllerFactory.Setup(c => c.CreateController(It.IsAny<ActionContext>()))

View File

@ -27,9 +27,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test
.Returns(httpRequest);
httpContext.SetupGet(c => c.RequestServices)
.Returns(services);
var routeContext = new RouteContext(httpContext.Object);
var controller = new TestController();
var context = new ActionContext(routeContext, new ActionDescriptor());
var context = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
var activator = new DefaultControllerActivator();
// Act
@ -50,9 +50,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(services);
var routeContext = new RouteContext(httpContext.Object);
var controller = new TestController();
var context = new ActionContext(routeContext, new ActionDescriptor());
var context = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
var activator = new DefaultControllerActivator();
// Act
@ -74,10 +74,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(services);
var routeContext = new RouteContext(httpContext.Object);
var controller = new TestController();
var context = new ActionContext(routeContext, new ActionDescriptor());
var context = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
var activator = new DefaultControllerActivator();
@ -98,9 +97,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(services);
var routeContext = new RouteContext(httpContext.Object);
var controller = new TestController();
var context = new ActionContext(routeContext, new ActionDescriptor());
var context = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
var activator = new DefaultControllerActivator();
// Act
@ -121,9 +120,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test
.Returns(Mock.Of<HttpResponse>());
httpContext.SetupGet(c => c.RequestServices)
.Returns(services);
var routeContext = new RouteContext(httpContext.Object);
var controller = new TestController();
var context = new ActionContext(routeContext, new ActionDescriptor());
var context = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
var activator = new DefaultControllerActivator();
// Act

View File

@ -104,8 +104,8 @@ namespace Microsoft.AspNet.Mvc
var httpContext = new Mock<DefaultHttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(serviceProvider);
var routeContext = new RouteContext(httpContext.Object);
var actionContext = new ActionContext(routeContext, new ActionDescriptor());
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
return new ViewContext(actionContext,
Mock.Of<IView>(),
new ViewDataDictionary(new EmptyModelMetadataProvider()),

View File

@ -3,9 +3,8 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Core;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Routing;
using Moq;
@ -53,8 +52,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test
{
// Arrange
var actionContext = new ActionContext(
new RouteContext(Mock.Of<HttpContext>()),
Mock.Of<ActionDescriptor>());
new DefaultHttpContext(),
new RouteData(),
new ControllerActionDescriptor());
var metadataProvider = new DataAnnotationsModelMetadataProvider();
var modelMetadata = metadataProvider.GetMetadataForType(
@ -81,8 +81,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test
var methodInfo = type.GetMethod("ParameterWithNoBindAttribute");
var actionContext = new ActionContext(
new RouteContext(Mock.Of<HttpContext>()),
Mock.Of<ActionDescriptor>());
new DefaultHttpContext(),
new RouteData(),
Mock.Of<ControllerActionDescriptor>());
var metadataProvider = new DataAnnotationsModelMetadataProvider();
var modelMetadata = metadataProvider.GetMetadataForParameter(modelAccessor: null,
@ -112,8 +113,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test
var methodInfo = type.GetMethod(actionMethodName);
var actionContext = new ActionContext(
new RouteContext(Mock.Of<HttpContext>()),
Mock.Of<ActionDescriptor>());
new DefaultHttpContext(),
new RouteData(),
Mock.Of<ControllerActionDescriptor>());
var metadataProvider = new DataAnnotationsModelMetadataProvider();
var modelMetadata = metadataProvider.GetMetadataForParameter(modelAccessor: null,
@ -143,8 +145,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test
var methodInfo = type.GetMethod(actionMethodName);
var actionContext = new ActionContext(
new RouteContext(Mock.Of<HttpContext>()),
Mock.Of<ActionDescriptor>());
new DefaultHttpContext(),
new RouteData(),
Mock.Of<ControllerActionDescriptor>());
var metadataProvider = new DataAnnotationsModelMetadataProvider();
var modelMetadata = metadataProvider.GetMetadataForParameter(modelAccessor: null,
@ -190,7 +193,10 @@ namespace Microsoft.AspNet.Mvc.Core.Test
})
.Returns(Task.FromResult(result: false));
var actionContext = new ActionContext(new RouteContext(Mock.Of<HttpContext>()), actionDescriptor);
var actionContext = new ActionContext(
new DefaultHttpContext(),
new RouteData(),
actionDescriptor);
var actionBindingContext = new ActionBindingContext()
{
@ -238,7 +244,10 @@ namespace Microsoft.AspNet.Mvc.Core.Test
})
.Returns(Task.FromResult(result: true));
var actionContext = new ActionContext(new RouteContext(Mock.Of<HttpContext>()), actionDescriptor);
var actionContext = new ActionContext(
new DefaultHttpContext(),
new RouteData(),
actionDescriptor);
var actionBindingContext = new ActionBindingContext()
{
@ -293,7 +302,10 @@ namespace Microsoft.AspNet.Mvc.Core.Test
})
.Returns(Task.FromResult(result: true));
var actionContext = new ActionContext(new RouteContext(Mock.Of<HttpContext>()), actionDescriptor);
var actionContext = new ActionContext(
new DefaultHttpContext(),
new RouteData(),
actionDescriptor);
var actionBindingContext = new ActionBindingContext()
{

View File

@ -52,7 +52,7 @@ namespace Microsoft.AspNet.Mvc
private static ViewComponentContext GetViewComponentContext(IView view, Stream stream)
{
var actionContext = new ActionContext(new RouteContext(new DefaultHttpContext()), new ActionDescriptor());
var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
var viewContext = new ViewContext(actionContext, view, viewData, TextWriter.Null);
var writer = new StreamWriter(stream) { AutoFlush = true };

View File

@ -91,7 +91,7 @@ namespace Microsoft.AspNet.Mvc
private static ViewComponentContext GetViewComponentContext(IView view, Stream stream)
{
var actionContext = new ActionContext(new RouteContext(new DefaultHttpContext()), new ActionDescriptor());
var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
var viewContext = new ViewContext(actionContext, view, viewData, TextWriter.Null);
var writer = new StreamWriter(stream) { AutoFlush = true };

View File

@ -300,7 +300,7 @@ namespace Microsoft.AspNet.Mvc
private static ViewComponentContext GetViewComponentContext(IView view, ViewDataDictionary viewData)
{
var actionContext = new ActionContext(new RouteContext(new DefaultHttpContext()), new ActionDescriptor());
var actionContext = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
var viewContext = new ViewContext(actionContext, view, viewData, TextWriter.Null);
var viewComponentContext = new ViewComponentContext(typeof(object).GetTypeInfo(), viewContext, TextWriter.Null);
return viewComponentContext;

View File

@ -34,8 +34,8 @@ namespace Microsoft.AspNet.Mvc.Razor
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(serviceProvider.Object);
var routeContext = new RouteContext(httpContext.Object);
var actionContext = new ActionContext(routeContext, new ActionDescriptor());
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
var viewContext = new ViewContext(actionContext,
Mock.Of<IView>(),
new ViewDataDictionary(new EmptyModelMetadataProvider()),
@ -64,8 +64,8 @@ namespace Microsoft.AspNet.Mvc.Razor
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(serviceProvider.Object);
var routeContext = new RouteContext(httpContext.Object);
var actionContext = new ActionContext(routeContext, new ActionDescriptor());
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
var viewContext = new ViewContext(actionContext,
Mock.Of<IView>(),
new ViewDataDictionary(new EmptyModelMetadataProvider()),
@ -99,8 +99,8 @@ namespace Microsoft.AspNet.Mvc.Razor
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(serviceProvider.Object);
var routeContext = new RouteContext(httpContext.Object);
var actionContext = new ActionContext(routeContext, new ActionDescriptor());
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider())
{
Model = new MyModel()
@ -134,8 +134,8 @@ namespace Microsoft.AspNet.Mvc.Razor
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(serviceProvider.Object);
var routeContext = new RouteContext(httpContext.Object);
var actionContext = new ActionContext(routeContext, new ActionDescriptor());
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
var viewData = new ViewDataDictionary<MyModel>(new EmptyModelMetadataProvider())
{
Model = new MyModel()
@ -169,8 +169,8 @@ namespace Microsoft.AspNet.Mvc.Razor
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(serviceProvider.Object);
var routeContext = new RouteContext(httpContext.Object);
var actionContext = new ActionContext(routeContext, new ActionDescriptor());
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
var viewContext = new ViewContext(actionContext,
Mock.Of<IView>(),
@ -235,8 +235,6 @@ namespace Microsoft.AspNet.Mvc.Razor
}
}
private class MyModel
{
}

View File

@ -85,8 +85,8 @@ namespace Microsoft.AspNet.Mvc.Razor
var httpContext = new Mock<HttpContext>();
httpContext.SetupGet(c => c.RequestServices)
.Returns(serviceProvider.Object);
var routeContext = new RouteContext(httpContext.Object);
var actionContext = new ActionContext(routeContext, new ActionDescriptor());
var actionContext = new ActionContext(httpContext.Object, new RouteData(), new ActionDescriptor());
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider());
var viewContext = new ViewContext(actionContext,
Mock.Of<IView>(),

View File

@ -26,7 +26,7 @@ namespace System.Web.Http
var stream = new MemoryStream();
httpContext.Response.Body = stream;
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var result = new BadRequestErrorMessageResult("Error");
// Act
@ -46,7 +46,7 @@ namespace System.Web.Http
var stream = new MemoryStream();
httpContext.Response.Body = stream;
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var result = new BadRequestErrorMessageResult("Error");
// Act

View File

@ -15,7 +15,7 @@ namespace System.Web.Http
public async Task ConflictResult_SetsStatusCode()
{
// Arrange
var context = new ActionContext(new RouteContext(new DefaultHttpContext()), new ActionDescriptor());
var context = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
var result = new ConflictResult();
// Act

View File

@ -26,7 +26,7 @@ namespace System.Web.Http
var stream = new MemoryStream();
httpContext.Response.Body = stream;
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var result = new ExceptionResult(new Exception("hello, world!"), includeErrorDetail: false);
// Act
@ -46,7 +46,7 @@ namespace System.Web.Http
var stream = new MemoryStream();
httpContext.Response.Body = stream;
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var result = new ExceptionResult(new Exception("hello, world!"), includeErrorDetail: false);
// Act

View File

@ -15,7 +15,7 @@ namespace System.Web.Http
public async Task InternalServerErrorResult_SetsStatusCode()
{
// Arrange
var context = new ActionContext(new RouteContext(new DefaultHttpContext()), new ActionDescriptor());
var context = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
var result = new InternalServerErrorResult();
// Act

View File

@ -27,7 +27,7 @@ namespace System.Web.Http
var stream = new MemoryStream();
httpContext.Response.Body = stream;
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var modelState = new ModelStateDictionary();
modelState.AddModelError("product.Name", "Name is required.");
@ -51,7 +51,7 @@ namespace System.Web.Http
var stream = new MemoryStream();
httpContext.Response.Body = stream;
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var modelState = new ModelStateDictionary();
modelState.AddModelError("product.Name", "Name is required.");

View File

@ -27,7 +27,7 @@ namespace System.Web.Http
var stream = new MemoryStream();
httpContext.Response.Body = stream;
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var result = new NegotiatedContentResult<Product>(HttpStatusCode.Ambiguous, new Product());
// Act
@ -47,7 +47,7 @@ namespace System.Web.Http
var stream = new MemoryStream();
httpContext.Response.Body = stream;
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var result = new NegotiatedContentResult<Product>(HttpStatusCode.Ambiguous, new Product());
// Act

View File

@ -26,7 +26,7 @@ namespace System.Web.Http
var stream = new MemoryStream();
httpContext.Response.Body = stream;
var context = new ActionContext(new RouteContext(httpContext), new ActionDescriptor());
var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var result = new OkNegotiatedContentResult<Product>(new Product());
// Act

View File

@ -15,7 +15,7 @@ namespace System.Web.Http
public async Task OkResult_SetsStatusCode()
{
// Arrange
var context = new ActionContext(new RouteContext(new DefaultHttpContext()), new ActionDescriptor());
var context = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
var result = new OkResult();
// Act

View File

@ -27,7 +27,7 @@ namespace System.Web.Http
httpContext.User = new ClaimsPrincipal();
var routeContext = new RouteContext(httpContext);
var actionContext = new ActionContext(routeContext, new ActionDescriptor());
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
// Act
controller.ActionContext = actionContext;