1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This software is subject to the Microsoft Public License (Ms-PL).
* A copy of the license can be found in the license.htm file included
* in this distribution.
*
* You must not remove this notice, or any other, from this software.
*
* ***************************************************************************/
namespace System.Web.Mvc {
using System;
using System.Diagnostics.CodeAnalysis;
using System.Web;
using System.Web.Routing;
using System.Web.Mvc.Html;
// Though many of the properties on ControllerContext and its subclassed types are virtual, there are still sealed
// properties (like ControllerContext.RequestContext, ActionExecutingContext.Result, etc.). If these properties
// were virtual, a mocking framework might override them with incorrect behavior (property getters would return
// null, property setters would be no-ops). By sealing these properties, we are forcing them to have the default
// "get or store a value" semantics that they were intended to have.
public class ControllerContext {
private HttpContextBase _httpContext;
private RequestContext _requestContext;
private RouteData _routeData;
internal const string PARENT_ACTION_VIEWCONTEXT = "ParentActionViewContext";
// parameterless constructor used for mocking
public ControllerContext() {
}
// copy constructor - allows for subclassed types to take an existing ControllerContext as a parameter
// and we'll automatically set the appropriate properties
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
protected ControllerContext(ControllerContext controllerContext) {
if (controllerContext == null) {
throw new ArgumentNullException("controllerContext");
}
Controller = controllerContext.Controller;
RequestContext = controllerContext.RequestContext;
}
public ControllerContext(HttpContextBase httpContext, RouteData routeData, ControllerBase controller)
: this(new RequestContext(httpContext, routeData), controller) {
}
[SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors",
Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")]
public ControllerContext(RequestContext requestContext, ControllerBase controller) {
if (requestContext == null) {
throw new ArgumentNullException("requestContext");
}
if (controller == null) {
throw new ArgumentNullException("controller");
}
RequestContext = requestContext;
Controller = controller;
}
public virtual ControllerBase Controller {
get;
set;
}
public virtual HttpContextBase HttpContext {
get {
if (_httpContext == null) {
_httpContext = (_requestContext != null) ? _requestContext.HttpContext : new EmptyHttpContext();
}
return _httpContext;
}
set {
_httpContext = value;
}
}
public virtual bool IsChildAction {
get {
RouteData routeData = RouteData;
if (routeData == null) {
return false;
}
return routeData.DataTokens.ContainsKey(PARENT_ACTION_VIEWCONTEXT);
}
}
public ViewContext ParentActionViewContext {
get {
return RouteData.DataTokens[PARENT_ACTION_VIEWCONTEXT] as ViewContext;
}
}
public RequestContext RequestContext {
get {
if (_requestContext == null) {
// still need explicit calls to constructors since the property getters are virtual and might return null
HttpContextBase httpContext = HttpContext ?? new EmptyHttpContext();
RouteData routeData = RouteData ?? new RouteData();
_requestContext = new RequestContext(httpContext, routeData);
}
return _requestContext;
}
set {
_requestContext = value;
}
}
public virtual RouteData RouteData {
get {
if (_routeData == null) {
_routeData = (_requestContext != null) ? _requestContext.RouteData : new RouteData();
}
return _routeData;
}
set {
_routeData = value;
}
}
private sealed class EmptyHttpContext : HttpContextBase {
}
}
}
|