Merge pull request #1436 from esdrubal/readerwriterlockslim
[mono.git] / mcs / class / System.Web.Mvc3 / Mvc / Controller.cs
1 namespace System.Web.Mvc {
2     using System;
3     using System.Diagnostics.CodeAnalysis;
4     using System.Globalization;
5     using System.IO;
6     using System.Security.Principal;
7     using System.Text;
8     using System.Web;
9     using System.Web.Mvc.Resources;
10     using System.Web.Routing;
11
12     public abstract class Controller : ControllerBase, IActionFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter {
13
14         private IActionInvoker _actionInvoker;
15         private ModelBinderDictionary _binders;
16         private RouteCollection _routeCollection;
17         private ITempDataProvider _tempDataProvider;
18
19         public IActionInvoker ActionInvoker {
20             get {
21                 if (_actionInvoker == null) {
22                     _actionInvoker = CreateActionInvoker();
23                 }
24                 return _actionInvoker;
25             }
26             set {
27                 _actionInvoker = value;
28             }
29         }
30
31         [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Property is settable so that the dictionary can be provided for unit testing purposes.")]
32         protected internal ModelBinderDictionary Binders {
33             get {
34                 if (_binders == null) {
35                     _binders = ModelBinders.Binders;
36                 }
37                 return _binders;
38             }
39             set {
40                 _binders = value;
41             }
42         }
43
44         public HttpContextBase HttpContext {
45             get {
46                 return ControllerContext == null ? null : ControllerContext.HttpContext;
47             }
48         }
49
50         public ModelStateDictionary ModelState {
51             get {
52                 return ViewData.ModelState;
53             }
54         }
55
56         public HttpRequestBase Request {
57             get {
58                 return HttpContext == null ? null : HttpContext.Request;
59             }
60         }
61
62         public HttpResponseBase Response {
63             get {
64                 return HttpContext == null ? null : HttpContext.Response;
65             }
66         }
67
68         internal RouteCollection RouteCollection {
69             get {
70                 if (_routeCollection == null) {
71                     _routeCollection = RouteTable.Routes;
72                 }
73                 return _routeCollection;
74             }
75             set {
76                 _routeCollection = value;
77             }
78         }
79
80         public RouteData RouteData {
81             get {
82                 return ControllerContext == null ? null : ControllerContext.RouteData;
83             }
84         }
85
86         public HttpServerUtilityBase Server {
87             get {
88                 return HttpContext == null ? null : HttpContext.Server;
89             }
90         }
91
92         public HttpSessionStateBase Session {
93             get {
94                 return HttpContext == null ? null : HttpContext.Session;
95             }
96         }
97
98         public ITempDataProvider TempDataProvider {
99             get {
100                 if (_tempDataProvider == null) {
101                     _tempDataProvider = CreateTempDataProvider();
102                 }
103                 return _tempDataProvider;
104             }
105             set {
106                 _tempDataProvider = value;
107             }
108         }
109
110         public UrlHelper Url {
111             get;
112             set;
113         }
114
115         public IPrincipal User {
116             get {
117                 return HttpContext == null ? null : HttpContext.User;
118             }
119         }
120
121         [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", Justification = "'Content' refers to ContentResult type; 'content' refers to ContentResult.Content property.")]
122         protected internal ContentResult Content(string content) {
123             return Content(content, null /* contentType */);
124         }
125
126         [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", Justification = "'Content' refers to ContentResult type; 'content' refers to ContentResult.Content property.")]
127         protected internal ContentResult Content(string content, string contentType) {
128             return Content(content, contentType, null /* contentEncoding */);
129         }
130
131         [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", Justification = "'Content' refers to ContentResult type; 'content' refers to ContentResult.Content property.")]
132         protected internal virtual ContentResult Content(string content, string contentType, Encoding contentEncoding) {
133             return new ContentResult {
134                 Content = content,
135                 ContentType = contentType,
136                 ContentEncoding = contentEncoding
137             };
138         }
139
140         protected virtual IActionInvoker CreateActionInvoker() {
141             return new ControllerActionInvoker();
142         }
143
144         protected virtual ITempDataProvider CreateTempDataProvider() {
145             return new SessionStateTempDataProvider();
146         }
147
148         // The default invoker will never match methods defined on the Controller type, so
149         // the Dispose() method is not web-callable.  However, in general, since implicitly-
150         // implemented interface methods are public, they are web-callable unless decorated with
151         // [NonAction].
152         public void Dispose() {
153             Dispose(true /* disposing */);
154             GC.SuppressFinalize(this);
155         }
156
157         protected virtual void Dispose(bool disposing) {
158         }
159
160         protected override void ExecuteCore() {
161             // If code in this method needs to be updated, please also check the BeginExecuteCore() and
162             // EndExecuteCore() methods of AsyncController to see if that code also must be updated.
163
164             PossiblyLoadTempData();
165             try {
166                 string actionName = RouteData.GetRequiredString("action");
167                 if (!ActionInvoker.InvokeAction(ControllerContext, actionName)) {
168                     HandleUnknownAction(actionName);
169                 }
170             }
171             finally {
172                 PossiblySaveTempData();
173             }
174         }
175
176         protected internal FileContentResult File(byte[] fileContents, string contentType) {
177             return File(fileContents, contentType, null /* fileDownloadName */);
178         }
179
180         protected internal virtual FileContentResult File(byte[] fileContents, string contentType, string fileDownloadName) {
181             return new FileContentResult(fileContents, contentType) { FileDownloadName = fileDownloadName };
182         }
183
184         protected internal FileStreamResult File(Stream fileStream, string contentType) {
185             return File(fileStream, contentType, null /* fileDownloadName */);
186         }
187
188         protected internal virtual FileStreamResult File(Stream fileStream, string contentType, string fileDownloadName) {
189             return new FileStreamResult(fileStream, contentType) { FileDownloadName = fileDownloadName };
190         }
191
192         protected internal FilePathResult File(string fileName, string contentType) {
193             return File(fileName, contentType, null /* fileDownloadName */);
194         }
195
196         protected internal virtual FilePathResult File(string fileName, string contentType, string fileDownloadName) {
197             return new FilePathResult(fileName, contentType) { FileDownloadName = fileDownloadName };
198         }
199
200         protected virtual void HandleUnknownAction(string actionName) {
201             throw new HttpException(404, String.Format(CultureInfo.CurrentCulture,
202                 MvcResources.Controller_UnknownAction, actionName, GetType().FullName));
203         }
204
205         protected internal HttpNotFoundResult HttpNotFound() {
206             return HttpNotFound(null);
207         }
208
209         protected internal virtual HttpNotFoundResult HttpNotFound(string statusDescription) {
210             return new HttpNotFoundResult(statusDescription);
211         }
212
213         protected internal virtual JavaScriptResult JavaScript(string script) {
214             return new JavaScriptResult { Script = script };
215         }
216
217         protected internal JsonResult Json(object data) {
218             return Json(data, null /* contentType */, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
219         }
220
221         protected internal JsonResult Json(object data, string contentType) {
222             return Json(data, contentType, null /* contentEncoding */, JsonRequestBehavior.DenyGet);
223         }
224
225         protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding) {
226             return Json(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet);
227         }
228
229         protected internal JsonResult Json(object data, JsonRequestBehavior behavior) {
230             return Json(data, null /* contentType */, null /* contentEncoding */, behavior);
231         }
232
233         protected internal JsonResult Json(object data, string contentType, JsonRequestBehavior behavior) {
234             return Json(data, contentType, null /* contentEncoding */, behavior);
235         }
236
237         protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) {
238             return new JsonResult {
239                 Data = data,
240                 ContentType = contentType,
241                 ContentEncoding = contentEncoding,
242                 JsonRequestBehavior = behavior
243             };
244         }
245
246         protected override void Initialize(RequestContext requestContext) {
247             base.Initialize(requestContext);
248             Url = new UrlHelper(requestContext);
249         }
250
251         protected virtual void OnActionExecuting(ActionExecutingContext filterContext) {
252         }
253
254         protected virtual void OnActionExecuted(ActionExecutedContext filterContext) {
255         }
256
257         protected virtual void OnAuthorization(AuthorizationContext filterContext) {
258         }
259
260         protected virtual void OnException(ExceptionContext filterContext) {
261         }
262
263         protected virtual void OnResultExecuted(ResultExecutedContext filterContext) {
264         }
265
266         protected virtual void OnResultExecuting(ResultExecutingContext filterContext) {
267         }
268
269         protected internal PartialViewResult PartialView() {
270             return PartialView(null /* viewName */, null /* model */);
271         }
272
273         protected internal PartialViewResult PartialView(object model) {
274             return PartialView(null /* viewName */, model);
275         }
276
277         protected internal PartialViewResult PartialView(string viewName) {
278             return PartialView(viewName, null /* model */);
279         }
280
281         protected internal virtual PartialViewResult PartialView(string viewName, object model) {
282             if (model != null) {
283                 ViewData.Model = model;
284             }
285
286             return new PartialViewResult {
287                 ViewName = viewName,
288                 ViewData = ViewData,
289                 TempData = TempData
290             };
291         }
292
293         internal void PossiblyLoadTempData() {
294             if (!ControllerContext.IsChildAction) {
295                 TempData.Load(ControllerContext, TempDataProvider);
296             }
297         }
298
299         internal void PossiblySaveTempData() {
300             if (!ControllerContext.IsChildAction) {
301                 TempData.Save(ControllerContext, TempDataProvider);
302             }
303         }
304
305         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", Justification = "Response.Redirect() takes its URI as a string parameter.")]
306         protected internal virtual RedirectResult Redirect(string url) {
307             if (String.IsNullOrEmpty(url)) {
308                 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "url");
309             }
310
311             return new RedirectResult(url);
312         }
313
314         [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", Justification = "Response.RedirectPermanent() takes its URI as a string parameter.")]
315         protected internal virtual RedirectResult RedirectPermanent(string url) {
316             if (String.IsNullOrEmpty(url)) {
317                 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "url");
318             }
319
320             return new RedirectResult(url, permanent: true);
321         }
322
323         protected internal RedirectToRouteResult RedirectToAction(string actionName) {
324             return RedirectToAction(actionName, (RouteValueDictionary)null);
325         }
326
327         protected internal RedirectToRouteResult RedirectToAction(string actionName, object routeValues) {
328             return RedirectToAction(actionName, new RouteValueDictionary(routeValues));
329         }
330
331         protected internal RedirectToRouteResult RedirectToAction(string actionName, RouteValueDictionary routeValues) {
332             return RedirectToAction(actionName, null /* controllerName */, routeValues);
333         }
334
335         protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName) {
336             return RedirectToAction(actionName, controllerName, (RouteValueDictionary)null);
337         }
338
339         protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName, object routeValues) {
340             return RedirectToAction(actionName, controllerName, new RouteValueDictionary(routeValues));
341         }
342
343         protected internal virtual RedirectToRouteResult RedirectToAction(string actionName, string controllerName, RouteValueDictionary routeValues) {
344             RouteValueDictionary mergedRouteValues;
345
346             if (RouteData == null) {
347                 mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, null, routeValues, includeImplicitMvcValues: true);
348             }
349             else {
350                 mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, RouteData.Values, routeValues, includeImplicitMvcValues: true);
351             }
352
353             return new RedirectToRouteResult(mergedRouteValues);
354         }
355
356         protected internal RedirectToRouteResult RedirectToActionPermanent(string actionName) {
357             return RedirectToActionPermanent(actionName, (RouteValueDictionary)null);
358         }
359
360         protected internal RedirectToRouteResult RedirectToActionPermanent(string actionName, object routeValues) {
361             return RedirectToActionPermanent(actionName, new RouteValueDictionary(routeValues));
362         }
363
364         protected internal RedirectToRouteResult RedirectToActionPermanent(string actionName, RouteValueDictionary routeValues) {
365             return RedirectToActionPermanent(actionName, null /* controllerName */, routeValues);
366         }
367
368         protected internal RedirectToRouteResult RedirectToActionPermanent(string actionName, string controllerName) {
369             return RedirectToActionPermanent(actionName, controllerName, (RouteValueDictionary)null);
370         }
371
372         protected internal RedirectToRouteResult RedirectToActionPermanent(string actionName, string controllerName, object routeValues) {
373             return RedirectToActionPermanent(actionName, controllerName, new RouteValueDictionary(routeValues));
374         }
375
376         protected internal virtual RedirectToRouteResult RedirectToActionPermanent(string actionName, string controllerName, RouteValueDictionary routeValues) {
377             RouteValueDictionary implicitRouteValues = (RouteData != null) ? RouteData.Values : null;
378
379             RouteValueDictionary mergedRouteValues =
380                 RouteValuesHelpers.MergeRouteValues(actionName, controllerName, implicitRouteValues, routeValues, includeImplicitMvcValues: true);
381
382             return new RedirectToRouteResult(null, mergedRouteValues, permanent: true);
383         }
384
385         protected internal RedirectToRouteResult RedirectToRoute(object routeValues) {
386             return RedirectToRoute(new RouteValueDictionary(routeValues));
387         }
388
389         protected internal RedirectToRouteResult RedirectToRoute(RouteValueDictionary routeValues) {
390             return RedirectToRoute(null /* routeName */, routeValues);
391         }
392
393         protected internal RedirectToRouteResult RedirectToRoute(string routeName) {
394             return RedirectToRoute(routeName, (RouteValueDictionary)null);
395         }
396
397         protected internal RedirectToRouteResult RedirectToRoute(string routeName, object routeValues) {
398             return RedirectToRoute(routeName, new RouteValueDictionary(routeValues));
399         }
400
401         protected internal virtual RedirectToRouteResult RedirectToRoute(string routeName, RouteValueDictionary routeValues) {
402             return new RedirectToRouteResult(routeName, RouteValuesHelpers.GetRouteValues(routeValues));
403         }
404
405         protected internal RedirectToRouteResult RedirectToRoutePermanent(object routeValues) {
406             return RedirectToRoutePermanent(new RouteValueDictionary(routeValues));
407         }
408
409         protected internal RedirectToRouteResult RedirectToRoutePermanent(RouteValueDictionary routeValues) {
410             return RedirectToRoutePermanent(null /* routeName */, routeValues);
411         }
412
413         protected internal RedirectToRouteResult RedirectToRoutePermanent(string routeName) {
414             return RedirectToRoutePermanent(routeName, (RouteValueDictionary)null);
415         }
416
417         protected internal RedirectToRouteResult RedirectToRoutePermanent(string routeName, object routeValues) {
418             return RedirectToRoutePermanent(routeName, new RouteValueDictionary(routeValues));
419         }
420
421         protected internal virtual RedirectToRouteResult RedirectToRoutePermanent(string routeName, RouteValueDictionary routeValues) {
422             return new RedirectToRouteResult(routeName, RouteValuesHelpers.GetRouteValues(routeValues), permanent: true);
423         }
424
425         protected internal bool TryUpdateModel<TModel>(TModel model) where TModel : class {
426             return TryUpdateModel(model, null, null, null, ValueProvider);
427         }
428
429         protected internal bool TryUpdateModel<TModel>(TModel model, string prefix) where TModel : class {
430             return TryUpdateModel(model, prefix, null, null, ValueProvider);
431         }
432
433         protected internal bool TryUpdateModel<TModel>(TModel model, string[] includeProperties) where TModel : class {
434             return TryUpdateModel(model, null, includeProperties, null, ValueProvider);
435         }
436
437         protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties) where TModel : class {
438             return TryUpdateModel(model, prefix, includeProperties, null, ValueProvider);
439         }
440
441         protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) where TModel : class {
442             return TryUpdateModel(model, prefix, includeProperties, excludeProperties, ValueProvider);
443         }
444
445         protected internal bool TryUpdateModel<TModel>(TModel model, IValueProvider valueProvider) where TModel : class {
446             return TryUpdateModel(model, null, null, null, valueProvider);
447         }
448
449         protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, IValueProvider valueProvider) where TModel : class {
450             return TryUpdateModel(model, prefix, null, null, valueProvider);
451         }
452
453         protected internal bool TryUpdateModel<TModel>(TModel model, string[] includeProperties, IValueProvider valueProvider) where TModel : class {
454             return TryUpdateModel(model, null, includeProperties, null, valueProvider);
455         }
456
457         protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, IValueProvider valueProvider) where TModel : class {
458             return TryUpdateModel(model, prefix, includeProperties, null, valueProvider);
459         }
460
461         protected internal bool TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IValueProvider valueProvider) where TModel : class {
462             if (model == null) {
463                 throw new ArgumentNullException("model");
464             }
465             if (valueProvider == null) {
466                 throw new ArgumentNullException("valueProvider");
467             }
468
469             Predicate<string> propertyFilter = propertyName => BindAttribute.IsPropertyAllowed(propertyName, includeProperties, excludeProperties);
470             IModelBinder binder = Binders.GetBinder(typeof(TModel));
471
472             ModelBindingContext bindingContext = new ModelBindingContext() {
473                 ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(TModel)),
474                 ModelName = prefix,
475                 ModelState = ModelState,
476                 PropertyFilter = propertyFilter,
477                 ValueProvider = valueProvider
478             };
479             binder.BindModel(ControllerContext, bindingContext);
480             return ModelState.IsValid;
481         }
482
483         protected internal bool TryValidateModel(object model) {
484             return TryValidateModel(model, null /* prefix */);
485         }
486
487         protected internal bool TryValidateModel(object model, string prefix) {
488             if (model == null) {
489                 throw new ArgumentNullException("model");
490             }
491
492             ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType());
493
494             foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(metadata, ControllerContext).Validate(null)) {
495                 ModelState.AddModelError(DefaultModelBinder.CreateSubPropertyName(prefix, validationResult.MemberName), validationResult.Message);
496             }
497
498             return ModelState.IsValid;
499         }
500
501         protected internal void UpdateModel<TModel>(TModel model) where TModel : class {
502             UpdateModel(model, null, null, null, ValueProvider);
503         }
504
505         protected internal void UpdateModel<TModel>(TModel model, string prefix) where TModel : class {
506             UpdateModel(model, prefix, null, null, ValueProvider);
507         }
508
509         protected internal void UpdateModel<TModel>(TModel model, string[] includeProperties) where TModel : class {
510             UpdateModel(model, null, includeProperties, null, ValueProvider);
511         }
512
513         protected internal void UpdateModel<TModel>(TModel model, string prefix, string[] includeProperties) where TModel : class {
514             UpdateModel(model, prefix, includeProperties, null, ValueProvider);
515         }
516
517         protected internal void UpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) where TModel : class {
518             UpdateModel(model, prefix, includeProperties, excludeProperties, ValueProvider);
519         }
520
521         protected internal void UpdateModel<TModel>(TModel model, IValueProvider valueProvider) where TModel : class {
522             UpdateModel(model, null, null, null, valueProvider);
523         }
524
525         protected internal void UpdateModel<TModel>(TModel model, string prefix, IValueProvider valueProvider) where TModel : class {
526             UpdateModel(model, prefix, null, null, valueProvider);
527         }
528
529         protected internal void UpdateModel<TModel>(TModel model, string[] includeProperties, IValueProvider valueProvider) where TModel : class {
530             UpdateModel(model, null, includeProperties, null, valueProvider);
531         }
532
533         protected internal void UpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, IValueProvider valueProvider) where TModel : class {
534             UpdateModel(model, prefix, includeProperties, null, valueProvider);
535         }
536
537         protected internal void UpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IValueProvider valueProvider) where TModel : class {
538             bool success = TryUpdateModel(model, prefix, includeProperties, excludeProperties, valueProvider);
539             if (!success) {
540                 string message = String.Format(CultureInfo.CurrentCulture, MvcResources.Controller_UpdateModel_UpdateUnsuccessful,
541                     typeof(TModel).FullName);
542                 throw new InvalidOperationException(message);
543             }
544         }
545
546         protected internal void ValidateModel(object model) {
547             ValidateModel(model, null /* prefix */);
548         }
549
550         protected internal void ValidateModel(object model, string prefix) {
551             if (!TryValidateModel(model, prefix)) {
552                 throw new InvalidOperationException(
553                     String.Format(
554                         CultureInfo.CurrentCulture,
555                         MvcResources.Controller_Validate_ValidationFailed,
556                         model.GetType().FullName
557                     )
558                 );
559             }
560         }
561
562         protected internal ViewResult View() {
563             return View(null /* viewName */, null /* masterName */, null /* model */);
564         }
565
566         protected internal ViewResult View(object model) {
567             return View(null /* viewName */, null /* masterName */, model);
568         }
569
570         protected internal ViewResult View(string viewName) {
571             return View(viewName, null /* masterName */, null /* model */);
572         }
573
574         protected internal ViewResult View(string viewName, string masterName) {
575             return View(viewName, masterName, null /* model */);
576         }
577
578         protected internal ViewResult View(string viewName, object model) {
579             return View(viewName, null /* masterName */, model);
580         }
581
582         protected internal virtual ViewResult View(string viewName, string masterName, object model) {
583             if (model != null) {
584                 ViewData.Model = model;
585             }
586
587             return new ViewResult {
588                 ViewName = viewName,
589                 MasterName = masterName,
590                 ViewData = ViewData,
591                 TempData = TempData
592             };
593         }
594
595         [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", Justification = "The method name 'View' is a convenient shorthand for 'CreateViewResult'.")]
596         protected internal ViewResult View(IView view) {
597             return View(view, null /* model */);
598         }
599
600         [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", Justification = "The method name 'View' is a convenient shorthand for 'CreateViewResult'.")]
601         protected internal virtual ViewResult View(IView view, object model) {
602             if (model != null) {
603                 ViewData.Model = model;
604             }
605
606             return new ViewResult {
607                 View = view,
608                 ViewData = ViewData,
609                 TempData = TempData
610             };
611         }
612
613         #region IActionFilter Members
614         void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) {
615             OnActionExecuting(filterContext);
616         }
617
618         void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext) {
619             OnActionExecuted(filterContext);
620         }
621         #endregion
622
623         #region IAuthorizationFilter Members
624         void IAuthorizationFilter.OnAuthorization(AuthorizationContext filterContext) {
625             OnAuthorization(filterContext);
626         }
627         #endregion
628
629         #region IExceptionFilter Members
630         void IExceptionFilter.OnException(ExceptionContext filterContext) {
631             OnException(filterContext);
632         }
633         #endregion
634
635         #region IResultFilter Members
636         void IResultFilter.OnResultExecuting(ResultExecutingContext filterContext) {
637             OnResultExecuting(filterContext);
638         }
639
640         void IResultFilter.OnResultExecuted(ResultExecutedContext filterContext) {
641             OnResultExecuted(filterContext);
642         }
643         #endregion
644     }
645 }