Fixing an issue with output parameters that are of type IntPtr
[castle.git] / MonoRail / Castle.MonoRail.Framework / BaseHttpHandler.cs
blob92ef5fd3cdd50f08c7a1e9f550f6fefc5a766b26
1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.MonoRail.Framework
17 using System;
18 using System.Collections;
19 using System.Web;
20 using System.Web.SessionState;
21 using Adapters;
23 /// <summary>
24 /// Pendent
25 /// </summary>
26 public abstract class BaseHttpHandler : IHttpHandler
28 /// <summary>
29 /// The controller
30 /// </summary>
31 protected readonly IController controller;
32 /// <summary>
33 /// The controller context
34 /// </summary>
35 protected readonly IControllerContext controllerContext;
36 /// <summary>
37 /// The engine context
38 /// </summary>
39 protected readonly IEngineContext engineContext;
40 private readonly bool sessionless;
42 /// <summary>
43 /// Initializes a new instance of the <see cref="BaseHttpHandler"/> class.
44 /// </summary>
45 /// <param name="engineContext">The engine context.</param>
46 /// <param name="controller">The controller.</param>
47 /// <param name="controllerContext">The controller context.</param>
48 /// <param name="sessionless">if set to <c>true</c> then we wont have a session to work.</param>
49 protected BaseHttpHandler(IEngineContext engineContext,
50 IController controller, IControllerContext controllerContext, bool sessionless)
52 this.controller = controller;
53 this.controllerContext = controllerContext;
54 this.engineContext = engineContext;
55 this.sessionless = sessionless;
58 #region IHttpHandler
60 /// <summary>
61 /// Pendent
62 /// </summary>
63 /// <param name="context"></param>
64 public void ProcessRequest(HttpContext context)
66 Process(context);
69 /// <summary>
70 /// Pendent
71 /// </summary>
72 public bool IsReusable
74 get { return false; }
77 #endregion
79 /// <summary>
80 /// Performs the base work of MonoRail. Extracts
81 /// the information from the URL, obtain the controller
82 /// that matches this information and dispatch the execution
83 /// to it.
84 /// </summary>
85 /// <param name="context">The context.</param>
86 public virtual void Process(HttpContext context)
88 BeforeControllerProcess(context);
90 try
92 engineContext.Services.ExtensionManager.RaisePreProcessController(engineContext);
94 controller.Process(engineContext, controllerContext);
96 engineContext.Services.ExtensionManager.RaisePostProcessController(engineContext);
98 catch(Exception ex)
100 HttpResponse response = context.Response;
102 if (response.StatusCode == 200)
104 response.StatusCode = 500;
107 engineContext.LastException = ex;
109 engineContext.Services.ExtensionManager.RaiseUnhandledError(engineContext);
111 throw new MonoRailException("Error processing MonoRail request. Action " +
112 controllerContext.Action + " on controller " + controllerContext.Name, ex);
114 finally
116 AfterControllerProcess();
120 /// <summary>
121 /// Handles MonoRail's actions afters the cotroller action finished processing
122 /// </summary>
123 protected void AfterControllerProcess()
125 if (!sessionless)
127 PersistFlashItems();
130 PersistCustomSession();
132 ReleaseController(controller);
135 /// <summary>
136 /// Handles MonoRail's actions before the controller action started processing
137 /// </summary>
138 /// <param name="context">The context.</param>
139 protected void BeforeControllerProcess(HttpContext context)
141 if (!sessionless)
143 // Now we have a session
144 engineContext.Session = ResolveSession(context);
147 IDictionary session = engineContext.Session;
149 Flash flash;
151 if (session != null)
153 flash = new Flash((Flash) session[Flash.FlashKey]);
155 else
157 flash = new Flash();
160 engineContext.Flash = flash;
162 // items added to be used by the test context
163 context.Items["mr.controller"] = controller;
164 context.Items["mr.flash"] = engineContext.Flash;
165 context.Items["mr.propertybag"] = controllerContext.PropertyBag;
166 context.Items["mr.session"] = context.Session;
168 AcquireCustomSession();
171 /// <summary>
172 /// Resolves the session.
173 /// </summary>
174 /// <param name="context">The context.</param>
175 /// <returns></returns>
176 protected virtual IDictionary ResolveSession(HttpContext context)
178 object session;
180 if (context.Items["AspSession"] != null)
182 // Windows and Testing
183 session = context.Items["AspSession"];
185 else
187 // Mono
188 session = context.Session;
191 if (session is HttpSessionState)
193 return new SessionAdapter(session as HttpSessionState);
195 else
197 return (IDictionary)session;
201 /// <summary>
202 /// Acquires the custom session from the custom session.
203 /// </summary>
204 protected virtual void AcquireCustomSession()
206 engineContext.Services.ExtensionManager.RaiseAcquireRequestState(engineContext);
209 /// <summary>
210 /// Persists the custom session to the custom session.
211 /// </summary>
212 protected virtual void PersistCustomSession()
214 engineContext.Services.ExtensionManager.RaiseReleaseRequestState(engineContext);
217 private void ReleaseController(IController controller)
219 engineContext.Services.ControllerFactory.Release(controller);
222 private void PersistFlashItems()
224 Flash currentFlash = engineContext.Flash;
226 if (currentFlash == null) return;
228 currentFlash.Sweep();
230 if (currentFlash.HasItemsToKeep)
232 engineContext.Session[Flash.FlashKey] = currentFlash;
234 else if (engineContext.Session.Contains(Flash.FlashKey))
236 engineContext.Session.Remove(Flash.FlashKey);