1 /* ****************************************************************************
\r
3 * Copyright (c) Microsoft Corporation. All rights reserved.
\r
5 * This software is subject to the Microsoft Public License (Ms-PL).
\r
6 * A copy of the license can be found in the license.htm file included
\r
7 * in this distribution.
\r
9 * You must not remove this notice, or any other, from this software.
\r
11 * ***************************************************************************/
\r
13 namespace System.Web.Mvc {
\r
15 using System.Diagnostics.CodeAnalysis;
\r
17 using System.Web.Routing;
\r
19 // Though many of the properties on ControllerContext and its subclassed types are virtual, there are still sealed
\r
20 // properties (like ControllerContext.RequestContext, ActionExecutingContext.Result, etc.). If these properties
\r
21 // were virtual, a mocking framework might override them with incorrect behavior (property getters would return
\r
22 // null, property setters would be no-ops). By sealing these properties, we are forcing them to have the default
\r
23 // "get or store a value" semantics that they were intended to have.
\r
25 public class ControllerContext {
\r
27 private HttpContextBase _httpContext;
\r
28 private RequestContext _requestContext;
\r
29 private RouteData _routeData;
\r
31 // parameterless constructor used for mocking
\r
32 public ControllerContext() {
\r
35 // copy constructor - allows for subclassed types to take an existing ControllerContext as a parameter
\r
36 // and we'll automatically set the appropriate properties
\r
37 [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
\r
38 Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
\r
39 protected ControllerContext(ControllerContext controllerContext) {
\r
40 if (controllerContext == null) {
\r
41 throw new ArgumentNullException("controllerContext");
\r
44 Controller = controllerContext.Controller;
\r
45 RequestContext = controllerContext.RequestContext;
\r
48 public ControllerContext(HttpContextBase httpContext, RouteData routeData, ControllerBase controller)
\r
49 : this(new RequestContext(httpContext, routeData), controller) {
\r
52 [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
\r
53 Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
\r
54 public ControllerContext(RequestContext requestContext, ControllerBase controller) {
\r
55 if (requestContext == null) {
\r
56 throw new ArgumentNullException("requestContext");
\r
58 if (controller == null) {
\r
59 throw new ArgumentNullException("controller");
\r
62 RequestContext = requestContext;
\r
63 Controller = controller;
\r
66 public virtual ControllerBase Controller {
\r
71 public virtual HttpContextBase HttpContext {
\r
73 if (_httpContext == null) {
\r
74 _httpContext = (_requestContext != null) ? _requestContext.HttpContext : new EmptyHttpContext();
\r
76 return _httpContext;
\r
79 _httpContext = value;
\r
83 public RequestContext RequestContext {
\r
85 if (_requestContext == null) {
\r
86 // still need explicit calls to constructors since the property getters are virtual and might return null
\r
87 HttpContextBase httpContext = HttpContext ?? new EmptyHttpContext();
\r
88 RouteData routeData = RouteData ?? new RouteData();
\r
90 _requestContext = new RequestContext(httpContext, routeData);
\r
92 return _requestContext;
\r
95 _requestContext = value;
\r
99 public virtual RouteData RouteData {
\r
101 if (_routeData == null) {
\r
102 _routeData = (_requestContext != null) ? _requestContext.RouteData : new RouteData();
\r
107 _routeData = value;
\r
111 private sealed class EmptyHttpContext : HttpContextBase {
\r