New tests.
[mono.git] / mcs / class / System.Web.Mvc2 / System.Web.Mvc / AsyncController.cs
1 /* ****************************************************************************\r
2  *\r
3  * Copyright (c) Microsoft Corporation. All rights reserved.\r
4  *\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
8  *\r
9  * You must not remove this notice, or any other, from this software.\r
10  *\r
11  * ***************************************************************************/\r
12 \r
13 namespace System.Web.Mvc {\r
14     using System;\r
15     using System.Web.Mvc.Async;\r
16     using System.Web.Routing;\r
17 \r
18     public abstract class AsyncController : Controller, IAsyncManagerContainer, IAsyncController {\r
19 \r
20         private static readonly object _executeTag = new object();\r
21         private static readonly object _executeCoreTag = new object();\r
22 \r
23         private readonly AsyncManager _asyncManager = new AsyncManager();\r
24 \r
25         public AsyncManager AsyncManager {\r
26             get {\r
27                 return _asyncManager;\r
28             }\r
29         }\r
30 \r
31         protected virtual IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state) {\r
32             if (requestContext == null) {\r
33                 throw new ArgumentNullException("requestContext");\r
34             }\r
35 \r
36             VerifyExecuteCalledOnce();\r
37             Initialize(requestContext);\r
38             return AsyncResultWrapper.Begin(callback, state, BeginExecuteCore, EndExecuteCore, _executeTag);\r
39         }\r
40 \r
41         protected virtual IAsyncResult BeginExecuteCore(AsyncCallback callback, object state) {\r
42             // If code in this method needs to be updated, please also check the ExecuteCore() method\r
43             // of Controller to see if that code also must be updated.\r
44 \r
45             PossiblyLoadTempData();\r
46             try {\r
47                 string actionName = RouteData.GetRequiredString("action");\r
48                 IActionInvoker invoker = ActionInvoker;\r
49                 IAsyncActionInvoker asyncInvoker = invoker as IAsyncActionInvoker;\r
50                 if (asyncInvoker != null) {\r
51                     // asynchronous invocation\r
52                     BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) {\r
53                         return asyncInvoker.BeginInvokeAction(ControllerContext, actionName, asyncCallback, asyncState);\r
54                     };\r
55 \r
56                     EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) {\r
57                         if (!asyncInvoker.EndInvokeAction(asyncResult)) {\r
58                             HandleUnknownAction(actionName);\r
59                         }\r
60                     };\r
61 \r
62                     return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _executeCoreTag);\r
63                 }\r
64                 else {\r
65                     // synchronous invocation\r
66                     Action action = () => {\r
67                         if (!invoker.InvokeAction(ControllerContext, actionName)) {\r
68                             HandleUnknownAction(actionName);\r
69                         }\r
70                     };\r
71                     return AsyncResultWrapper.BeginSynchronous(callback, state, action, _executeCoreTag);\r
72                 }\r
73             }\r
74             catch {\r
75                 PossiblySaveTempData();\r
76                 throw;\r
77             }\r
78         }\r
79 \r
80         protected override IActionInvoker CreateActionInvoker() {\r
81             return new AsyncControllerActionInvoker();\r
82         }\r
83 \r
84         protected virtual void EndExecute(IAsyncResult asyncResult) {\r
85             AsyncResultWrapper.End(asyncResult, _executeTag);\r
86         }\r
87 \r
88         protected virtual void EndExecuteCore(IAsyncResult asyncResult) {\r
89             // If code in this method needs to be updated, please also check the ExecuteCore() method\r
90             // of Controller to see if that code also must be updated.\r
91 \r
92             try {\r
93                 AsyncResultWrapper.End(asyncResult, _executeCoreTag);\r
94             }\r
95             finally {\r
96                 PossiblySaveTempData();\r
97             }\r
98         }\r
99 \r
100         #region IAsyncController Members\r
101         IAsyncResult IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, object state) {\r
102             return BeginExecute(requestContext, callback, state);\r
103         }\r
104 \r
105         void IAsyncController.EndExecute(IAsyncResult asyncResult) {\r
106             EndExecute(asyncResult);\r
107         }\r
108         #endregion\r
109 \r
110     }\r
111 }\r