File: ControllerContext.cs

package info (click to toggle)
mono 2.6.7-5.1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 327,344 kB
  • ctags: 413,649
  • sloc: cs: 2,471,883; xml: 1,768,594; ansic: 350,665; sh: 13,644; makefile: 8,640; perl: 1,784; asm: 717; cpp: 209; python: 146; sql: 81; sed: 16
file content (134 lines) | stat: -rw-r--r-- 5,247 bytes parent folder | download | duplicates (2)
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 {
        }

    }
}