2005-06-05 Peter Bartok <pbartok@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.UI / Page.cs
1 //
2 // System.Web.UI.Page.cs
3 //
4 // Authors:
5 //   Duncan Mak  (duncan@ximian.com)
6 //   Gonzalo Paniagua (gonzalo@ximian.com)
7 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 //
9 // (C) 2002,2003 Ximian, Inc. (http://www.ximian.com)
10 // (c) 2003 Novell, Inc. (http://www.novell.com)
11 //
12
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System;
35 using System.Collections;
36 using System.Collections.Specialized;
37 using System.ComponentModel;
38 using System.ComponentModel.Design;
39 using System.ComponentModel.Design.Serialization;
40 using System.Globalization;
41 using System.IO;
42 using System.Security.Principal;
43 using System.Text;
44 using System.Threading;
45 using System.Web;
46 using System.Web.Caching;
47 using System.Web.SessionState;
48 using System.Web.Util;
49 #if NET_2_0
50 using System.Web.UI.HtmlControls;
51 #endif
52
53 namespace System.Web.UI
54 {
55
56 #if !NET_2_0
57 [RootDesignerSerializer ("Microsoft.VSDesigner.WebForms.RootCodeDomSerializer, " + Consts.AssemblyMicrosoft_VSDesigner, "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design, true)]
58 #endif
59 [DefaultEvent ("Load"), DesignerCategory ("ASPXCodeBehind")]
60 [ToolboxItem (false)]
61 [Designer ("System.Web.UI.Design.ControlDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]
62 public class Page : TemplateControl, IHttpHandler
63 {
64         private bool _viewState = true;
65         private bool _viewStateMac;
66         private string _errorPage;
67         private bool _isValid;
68         private bool _smartNavigation;
69         private int _transactionMode;
70         private HttpContext _context;
71         private ValidatorCollection _validators;
72         private bool renderingForm;
73         private object _savedViewState;
74         private ArrayList _requiresPostBack;
75         private ArrayList _requiresPostBackCopy;
76         private ArrayList requiresPostDataChanged;
77         private IPostBackEventHandler requiresRaiseEvent;
78         private NameValueCollection secondPostData;
79         private bool requiresPostBackScript;
80         private bool postBackScriptRendered;
81         bool handleViewState;
82         string viewStateUserKey;
83         NameValueCollection _requestValueCollection;
84         string clientTarget;
85         ClientScriptManager scriptManager;
86
87         [EditorBrowsable (EditorBrowsableState.Never)]
88         protected const string postEventArgumentID = "__EVENTARGUMENT";
89         [EditorBrowsable (EditorBrowsableState.Never)]
90         protected const string postEventSourceID = "__EVENTTARGET";
91
92 #if NET_2_0
93         internal const string CallbackArgumentID = "__CALLBACKARGUMENT";
94         internal const string CallbackSourceID = "__CALLBACKTARGET";
95         internal const string PreviousPageID = "__PREVIOUSPAGE";
96         
97         IPageHeader htmlHeader;
98         
99         MasterPage masterPage;
100         string masterPageFile;
101         
102         Page previousPage;
103         bool isCrossPagePostBack;
104         ArrayList requireStateControls;
105         Hashtable _validatorsByGroup;
106         HtmlForm _form;
107 #endif
108
109         #region Constructor
110         public Page ()
111         {
112                 scriptManager = new ClientScriptManager (this);
113                 Page = this;
114         }
115
116         #endregion              
117
118         #region Properties
119
120         [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
121         [Browsable (false)]
122         public HttpApplicationState Application
123         {
124                 get { return _context.Application; }
125         }
126
127         [EditorBrowsable (EditorBrowsableState.Never)]
128 #if NET_2_0
129         public bool AspCompatMode
130         {
131                 get { return false; }
132                 set { throw new NotImplementedException (); }
133         }
134 #else
135         protected bool AspCompatMode
136         {
137                 set { throw new NotImplementedException (); }
138         }
139 #endif
140
141         [EditorBrowsable (EditorBrowsableState.Never)]
142 #if NET_2_0
143     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
144     [BrowsableAttribute (false)]
145         public bool Buffer
146         {
147                 get { return Response.BufferOutput; }
148                 set { Response.BufferOutput = value; }
149         }
150 #else
151         protected bool Buffer
152         {
153                 set { Response.BufferOutput = value; }
154         }
155 #endif
156
157         [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
158         [Browsable (false)]
159         public Cache Cache
160         {
161                 get { return _context.Cache; }
162         }
163
164 #if NET_2_0
165     [EditorBrowsableAttribute (EditorBrowsableState.Advanced)]
166 #endif
167         [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
168         [Browsable (false), DefaultValue ("")]
169         [WebSysDescription ("Value do override the automatic browser detection and force the page to use the specified browser.")]
170         public string ClientTarget
171         {
172                 get { return (clientTarget == null) ? "" : clientTarget; }
173                 set {
174                         clientTarget = value;
175                         if (value == "")
176                                 clientTarget = null;
177                 }
178         }
179
180         [EditorBrowsable (EditorBrowsableState.Never)]
181 #if NET_2_0
182     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
183     [BrowsableAttribute (false)]
184         public int CodePage
185         {
186                 get { return Response.ContentEncoding.CodePage; }
187                 set { Response.ContentEncoding = Encoding.GetEncoding (value); }
188         }
189 #else
190         protected int CodePage
191         {
192                 set { Response.ContentEncoding = Encoding.GetEncoding (value); }
193         }
194 #endif
195
196         [EditorBrowsable (EditorBrowsableState.Never)]
197 #if NET_2_0
198     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
199     [BrowsableAttribute (false)]
200         public string ContentType
201         {
202                 get { return Response.ContentType; }
203                 set { Response.ContentType = value; }
204         }
205 #else
206         protected string ContentType
207         {
208                 set { Response.ContentType = value; }
209         }
210 #endif
211
212         protected override HttpContext Context
213         {
214                 get {
215                         if (_context == null)
216                                 return HttpContext.Current;
217
218                         return _context;
219                 }
220         }
221
222         [EditorBrowsable (EditorBrowsableState.Never)]
223 #if NET_2_0
224     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
225     [BrowsableAttribute (false)]
226         public string Culture
227         {
228                 get { return Thread.CurrentThread.CurrentCulture.Name; }
229                 set { Thread.CurrentThread.CurrentCulture = new CultureInfo (value); }
230         }
231 #else
232         protected string Culture
233         {
234                 set { Thread.CurrentThread.CurrentCulture = new CultureInfo (value); }
235         }
236 #endif
237
238         [Browsable (false)]
239         public override bool EnableViewState
240         {
241                 get { return _viewState; }
242                 set { _viewState = value; }
243         }
244
245 #if NET_2_0
246     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
247     [BrowsableAttribute (false)]
248 #endif
249         [EditorBrowsable (EditorBrowsableState.Never)]
250         protected bool EnableViewStateMac
251         {
252                 get { return _viewStateMac; }
253                 set { _viewStateMac = value; }
254         }
255
256         [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
257         [Browsable (false), DefaultValue ("")]
258         [WebSysDescription ("The URL of a page used for error redirection.")]
259         public string ErrorPage
260         {
261                 get { return _errorPage; }
262                 set {
263                         _errorPage = value;
264                         if (_context != null)
265                                 _context.ErrorPage = value;
266                 }
267         }
268
269 #if NET_2_0
270         [Obsolete]
271 #endif
272         [EditorBrowsable (EditorBrowsableState.Never)]
273         protected ArrayList FileDependencies
274         {
275                 set {
276                         if (Response != null)
277                                 Response.AddFileDependencies (value);
278                 }
279         }
280
281         [Browsable (false)]
282         public override string ID
283         {
284                 get { return base.ID; }
285                 set { base.ID = value; }
286         }
287
288         [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
289         [Browsable (false)]
290         public bool IsPostBack
291         {
292                 get {
293                         return _requestValueCollection != null;
294                 }
295         }
296
297         [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]
298         public bool IsReusable {
299                 get { return false; }
300         }
301
302         [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
303         [Browsable (false)]
304         public bool IsValid
305         {
306                 get { return _isValid; }
307         }
308
309         [EditorBrowsable (EditorBrowsableState.Never)]
310 #if NET_2_0
311     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
312     [BrowsableAttribute (false)]
313         public int LCID {
314                 get { return Thread.CurrentThread.CurrentCulture.LCID; }
315                 set { Thread.CurrentThread.CurrentCulture = new CultureInfo (value); }
316         }
317 #else
318         protected int LCID {
319                 set { Thread.CurrentThread.CurrentCulture = new CultureInfo (value); }
320         }
321 #endif
322
323         [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
324         [Browsable (false)]
325         public HttpRequest Request
326         {
327                 get { return _context.Request; }
328         }
329
330         [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
331         [Browsable (false)]
332         public HttpResponse Response
333         {
334                 get { return _context.Response; }
335         }
336
337         [EditorBrowsable (EditorBrowsableState.Never)]
338 #if NET_2_0
339     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
340     [BrowsableAttribute (false)]
341         public string ResponseEncoding
342         {
343                 get { return Response.ContentEncoding.WebName; }
344                 set { Response.ContentEncoding = Encoding.GetEncoding (value); }
345         }
346 #else
347         protected string ResponseEncoding
348         {
349                 set { Response.ContentEncoding = Encoding.GetEncoding (value); }
350         }
351 #endif
352
353         [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
354         [Browsable (false)]
355         public HttpServerUtility Server
356         {
357                 get {
358                         return Context.Server;
359                 }
360         }
361
362         [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
363         [Browsable (false)]
364         public virtual HttpSessionState Session
365         {
366                 get {
367                         if (_context.Session == null)
368                                 throw new HttpException ("Session state can only be used " +
369                                                 "when enableSessionState is set to true, either " +
370                                                 "in a configuration file or in the Page directive.");
371
372                         return _context.Session;
373                 }
374         }
375
376 #if NET_2_0
377     [FilterableAttribute (false)]
378 #endif
379         [Browsable (false)]
380         public bool SmartNavigation
381         {
382                 get { return _smartNavigation; }
383                 set { _smartNavigation = value; }
384         }
385
386         [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
387         [Browsable (false)]
388         public TraceContext Trace
389         {
390                 get { return Context.Trace; }
391         }
392
393         [EditorBrowsable (EditorBrowsableState.Never)]
394 #if NET_2_0
395     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
396     [BrowsableAttribute (false)]
397         public bool TraceEnabled
398         {
399                 get { return Trace.IsEnabled; }
400                 set { Trace.IsEnabled = value; }
401         }
402 #else
403         protected bool TraceEnabled
404         {
405                 set { Trace.IsEnabled = value; }
406         }
407 #endif
408
409         [EditorBrowsable (EditorBrowsableState.Never)]
410 #if NET_2_0
411     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
412     [BrowsableAttribute (false)]
413         public TraceMode TraceModeValue
414         {
415                 get { return Trace.TraceMode; }
416                 set { Trace.TraceMode = value; }
417         }
418 #else
419         protected TraceMode TraceModeValue
420         {
421                 set { Trace.TraceMode = value; }
422         }
423 #endif
424
425         [EditorBrowsable (EditorBrowsableState.Never)]
426 #if NET_2_0
427         public int TransactionMode
428         {
429                 get { return _transactionMode; }
430                 set { _transactionMode = value; }
431         }
432 #else
433         protected int TransactionMode
434         {
435                 set { _transactionMode = value; }
436         }
437 #endif
438
439         [EditorBrowsable (EditorBrowsableState.Never)]
440 #if NET_2_0
441     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
442     [BrowsableAttribute (false)]
443         public string UICulture
444         {
445                 get { return Thread.CurrentThread.CurrentUICulture.Name; }
446                 set { Thread.CurrentThread.CurrentUICulture = new CultureInfo (value); }
447         }
448 #else
449         protected string UICulture
450         {
451                 set { Thread.CurrentThread.CurrentUICulture = new CultureInfo (value); }
452         }
453 #endif
454
455         [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
456         [Browsable (false)]
457         public IPrincipal User
458         {
459                 get { return _context.User; }
460         }
461
462         [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
463         [Browsable (false)]
464         public ValidatorCollection Validators
465         {
466                 get { 
467                         if (_validators == null)
468                                 _validators = new ValidatorCollection ();
469                         return _validators;
470                 }
471         }
472
473         [MonoTODO ("Use this when encrypting/decrypting ViewState")]
474         [Browsable (false)]
475         public string ViewStateUserKey {
476                 get { return viewStateUserKey; }
477                 set { viewStateUserKey = value; }
478         }
479
480         [Browsable (false)]
481         public override bool Visible
482         {
483                 get { return base.Visible; }
484                 set { base.Visible = value; }
485         }
486
487         #endregion
488
489         #region Methods
490
491         [EditorBrowsable (EditorBrowsableState.Never)]
492         protected IAsyncResult AspCompatBeginProcessRequest (HttpContext context,
493                                                              AsyncCallback cb, 
494                                                              object extraData)
495         {
496                 throw new NotImplementedException ();
497         }
498
499         [EditorBrowsable (EditorBrowsableState.Never)]
500         protected void AspCompatEndProcessRequest (IAsyncResult result)
501         {
502                 throw new NotImplementedException ();
503         }
504         
505         [EditorBrowsable (EditorBrowsableState.Advanced)]
506         protected virtual HtmlTextWriter CreateHtmlTextWriter (TextWriter tw)
507         {
508                 return new HtmlTextWriter (tw);
509         }
510
511         [EditorBrowsable (EditorBrowsableState.Never)]
512         public void DesignerInitialize ()
513         {
514                 InitRecursive (null);
515         }
516
517         [EditorBrowsable (EditorBrowsableState.Advanced)]
518         protected virtual NameValueCollection DeterminePostBackMode ()
519         {
520                 if (_context == null)
521                         return null;
522
523                 HttpRequest req = _context.Request;
524                 if (req == null)
525                         return null;
526
527                 NameValueCollection coll = null;
528                 if (0 == String.Compare (Request.HttpMethod, "POST", true))
529                         coll =  req.Form;
530                 else 
531                         coll = req.QueryString;
532
533                 
534                 if (coll == null || coll ["__VIEWSTATE"] == null)
535                         return null;
536
537                 return coll;
538         }
539
540 #if NET_2_0
541         [Obsolete]
542 #endif
543         [EditorBrowsable (EditorBrowsableState.Advanced)]
544         public string GetPostBackClientEvent (Control control, string argument)
545         {
546                 return scriptManager.GetPostBackClientEvent (control, argument);
547         }
548
549 #if NET_2_0
550         [Obsolete]
551 #endif
552         [EditorBrowsable (EditorBrowsableState.Advanced)]
553         public string GetPostBackClientHyperlink (Control control, string argument)
554         {
555                 return scriptManager.GetPostBackClientHyperlink (control, argument);
556         }
557
558 #if NET_2_0
559         [Obsolete]
560 #endif
561         [EditorBrowsable (EditorBrowsableState.Advanced)]
562         public string GetPostBackEventReference (Control control)
563         {
564                 return scriptManager.GetPostBackEventReference (control);
565         }
566
567 #if NET_2_0
568         [Obsolete]
569 #endif
570         [EditorBrowsable (EditorBrowsableState.Advanced)]
571         public string GetPostBackEventReference (Control control, string argument)
572         {
573                 return scriptManager.GetPostBackEventReference (control, argument);
574         }
575
576         internal void RequiresPostBackScript ()
577         {
578                 requiresPostBackScript = true;
579         }
580
581         [EditorBrowsable (EditorBrowsableState.Never)]
582         public virtual int GetTypeHashCode ()
583         {
584                 return 0;
585         }
586
587         [EditorBrowsable (EditorBrowsableState.Never)]
588         protected virtual void InitOutputCache (int duration,
589                                                 string varyByHeader,
590                                                 string varyByCustom,
591                                                 OutputCacheLocation location,
592                                                 string varyByParam)
593         {
594                 HttpCachePolicy cache = _context.Response.Cache;
595                 bool set_vary = false;
596
597                 switch (location) {
598                 case OutputCacheLocation.Any:
599                         cache.SetCacheability (HttpCacheability.Public);
600                         cache.SetMaxAge (new TimeSpan (0, 0, duration));                
601                         cache.SetLastModified (_context.Timestamp);
602                         set_vary = true;
603                         break;
604                 case OutputCacheLocation.Client:
605                         cache.SetCacheability (HttpCacheability.Private);
606                         cache.SetMaxAge (new TimeSpan (0, 0, duration));                
607                         cache.SetLastModified (_context.Timestamp);
608                         break;
609                 case OutputCacheLocation.Downstream:
610                         cache.SetCacheability (HttpCacheability.Public);
611                         cache.SetMaxAge (new TimeSpan (0, 0, duration));                
612                         cache.SetLastModified (_context.Timestamp);
613                         break;
614                 case OutputCacheLocation.Server:                        
615                         cache.SetCacheability (HttpCacheability.Server);
616                         set_vary = true;
617                         break;
618                 case OutputCacheLocation.None:
619                         break;
620                 }
621
622                 if (set_vary) {
623                         if (varyByCustom != null)
624                                 cache.SetVaryByCustom (varyByCustom);
625
626                         if (varyByParam != null && varyByParam.Length > 0) {
627                                 string[] prms = varyByParam.Split (';');
628                                 foreach (string p in prms)
629                                         cache.VaryByParams [p.Trim ()] = true;
630                                 cache.VaryByParams.IgnoreParams = false;
631                         } else {
632                                 cache.VaryByParams.IgnoreParams = true;
633                         }
634                         
635                         if (varyByHeader != null && varyByHeader.Length > 0) {
636                                 string[] hdrs = varyByHeader.Split (';');
637                                 foreach (string h in hdrs)
638                                         cache.VaryByHeaders [h.Trim ()] = true;
639                         }
640                 }
641                         
642                 cache.Duration = duration;
643                 cache.SetExpires (_context.Timestamp.AddSeconds (duration));
644         }
645
646 #if NET_2_0
647         [Obsolete]
648 #else
649         [EditorBrowsable (EditorBrowsableState.Advanced)]
650 #endif
651         public bool IsClientScriptBlockRegistered (string key)
652         {
653                 return scriptManager.IsClientScriptBlockRegistered (key);
654         }
655
656 #if NET_2_0
657         [Obsolete]
658 #else
659         [EditorBrowsable (EditorBrowsableState.Advanced)]
660 #endif
661         public bool IsStartupScriptRegistered (string key)
662         {
663                 return scriptManager.IsStartupScriptRegistered (key);
664         }
665
666         public string MapPath (string virtualPath)
667         {
668                 return Request.MapPath (virtualPath);
669         }
670         
671         private void RenderPostBackScript (HtmlTextWriter writer, string formUniqueID)
672         {
673                 writer.WriteLine ("<input type=\"hidden\" name=\"{0}\" value=\"\" />", postEventSourceID);
674                 writer.WriteLine ("<input type=\"hidden\" name=\"{0}\" value=\"\" />", postEventArgumentID);
675                 writer.WriteLine ();
676                 writer.WriteLine ("<script language=\"javascript\">");
677                 writer.WriteLine ("<!--");
678
679                 if (Request.Browser.Browser == ("Netscape") && Request.Browser.MajorVersion == 4)
680                         writer.WriteLine ("\tvar theForm = document.{0};", formUniqueID);
681                 else
682                         writer.WriteLine ("\tvar theForm = document.getElementById ('{0}');", formUniqueID);
683
684                 writer.WriteLine ("\tfunction __doPostBack(eventTarget, eventArgument) {");
685                 writer.WriteLine ("\t\ttheForm.{0}.value = eventTarget;", postEventSourceID);
686                 writer.WriteLine ("\t\ttheForm.{0}.value = eventArgument;", postEventArgumentID);
687                 writer.WriteLine ("\t\ttheForm.submit();");
688                 writer.WriteLine ("\t}");
689                 writer.WriteLine ("// -->");
690                 writer.WriteLine ("</script>");
691         }
692
693         internal void OnFormRender (HtmlTextWriter writer, string formUniqueID)
694         {
695                 if (renderingForm)
696                         throw new HttpException ("Only 1 HtmlForm is allowed per page.");
697
698                 renderingForm = true;
699                 writer.WriteLine ();
700                 scriptManager.WriteHiddenFields (writer);
701                 if (requiresPostBackScript) {
702                         RenderPostBackScript (writer, formUniqueID);
703                         postBackScriptRendered = true;
704                 }
705
706                 if (handleViewState) {
707                         string vs = GetViewStateString ();
708                         writer.Write ("<input type=\"hidden\" name=\"__VIEWSTATE\" ");
709                         writer.WriteLine ("value=\"{0}\" />", vs);
710                 }
711
712                 scriptManager.WriteClientScriptBlocks (writer);
713         }
714
715         internal string GetViewStateString ()
716         {
717                 if (_savedViewState == null)
718                         return null;
719                 StringWriter sr = new StringWriter ();
720                 LosFormatter fmt = new LosFormatter ();
721                 fmt.Serialize (sr, _savedViewState);
722                 return sr.GetStringBuilder ().ToString ();
723         }
724
725         internal void OnFormPostRender (HtmlTextWriter writer, string formUniqueID)
726         {
727                 scriptManager.WriteArrayDeclares (writer);
728
729                 if (!postBackScriptRendered && requiresPostBackScript)
730                         RenderPostBackScript (writer, formUniqueID);
731
732                 scriptManager.WriteHiddenFields (writer);
733                 scriptManager.WriteClientScriptIncludes (writer);
734                 scriptManager.WriteStartupScriptBlocks (writer);
735                 renderingForm = false;
736                 postBackScriptRendered = false;
737         }
738
739         private void ProcessPostData (NameValueCollection data, bool second)
740         {
741                 if (data == null)
742                         return;
743
744                 if (_requiresPostBackCopy == null && _requiresPostBack != null)
745                         _requiresPostBackCopy = (ArrayList) _requiresPostBack.Clone ();
746
747                 Hashtable used = new Hashtable ();
748                 foreach (string id in data.AllKeys){
749                         if (id == "__VIEWSTATE" || id == postEventSourceID || id == postEventArgumentID)
750                                 continue;
751
752                         string real_id = id;
753                         int dot = real_id.IndexOf ('.');
754                         if (dot >= 1)
755                                 real_id = real_id.Substring (0, dot);
756                         
757                         if (real_id == null || used.ContainsKey (real_id))
758                                 continue;
759
760                         used.Add (real_id, real_id);
761
762                         Control ctrl = FindControl (real_id);
763                         if (ctrl != null){
764                                 IPostBackDataHandler pbdh = ctrl as IPostBackDataHandler;
765                                 IPostBackEventHandler pbeh = ctrl as IPostBackEventHandler;
766
767                                 if (pbdh == null) {
768                                         if (pbeh != null)
769                                                 RegisterRequiresRaiseEvent (pbeh);
770                                         continue;
771                                 }
772                 
773                                 if (pbdh.LoadPostData (real_id, data) == true) {
774                                         if (requiresPostDataChanged == null)
775                                                 requiresPostDataChanged = new ArrayList ();
776                                         requiresPostDataChanged.Add (pbdh);
777                                         if (_requiresPostBackCopy != null)
778                                                 _requiresPostBackCopy.Remove (ctrl.UniqueID);
779                                 }
780                         } else if (!second) {
781                                 if (secondPostData == null)
782                                         secondPostData = new NameValueCollection ();
783                                 secondPostData.Add (real_id, data [id]);
784                         }
785                 }
786
787                 ArrayList list1 = null;
788                 if (_requiresPostBackCopy != null && _requiresPostBackCopy.Count > 0) {
789                         string [] handlers = (string []) _requiresPostBackCopy.ToArray (typeof (string));
790                         foreach (string id in handlers) {
791                                 IPostBackDataHandler pbdh = FindControl (id) as IPostBackDataHandler;
792                                 if (pbdh != null) {                     
793                                         _requiresPostBackCopy.Remove (id);
794                                         if (pbdh.LoadPostData (id, data)) {
795                                                 if (requiresPostDataChanged == null)
796                                                         requiresPostDataChanged = new ArrayList ();
797         
798                                                 requiresPostDataChanged.Add (pbdh);
799                                         }
800                                 } else if (second) {
801                                         if (list1 == null)
802                                                 list1 = new ArrayList ();
803                                         list1.Add (id);
804                                 }
805                         }
806                 }
807                 _requiresPostBack = list1;
808         }
809
810         [EditorBrowsable (EditorBrowsableState.Never)]
811         public void ProcessRequest (HttpContext context)
812         {
813                 _context = context;
814                 if (clientTarget != null)
815                         Request.ClientTarget = clientTarget;
816
817                 WireupAutomaticEvents ();
818                 //-- Control execution lifecycle in the docs
819
820                 // Save culture information because it can be modified in FrameworkInitialize()
821                 CultureInfo culture = Thread.CurrentThread.CurrentCulture;
822                 CultureInfo uiculture = Thread.CurrentThread.CurrentUICulture;
823                 FrameworkInitialize ();
824                 context.ErrorPage = _errorPage;
825
826                 try {
827                         InternalProcessRequest ();
828                 } finally {
829                         try {
830                                 UnloadRecursive (true);
831                         } catch {}
832                         if (Thread.CurrentThread.CurrentCulture.Equals (culture) == false)
833                                 Thread.CurrentThread.CurrentCulture = culture;
834
835                         if (Thread.CurrentThread.CurrentUICulture.Equals (uiculture) == false)
836                                 Thread.CurrentThread.CurrentUICulture = uiculture;
837                 }
838         }
839         
840 #if NET_2_0
841         internal void ProcessCrossPagePostBack (HttpContext context)
842         {
843                 isCrossPagePostBack = true;
844                 ProcessRequest (context);
845         }
846 #endif
847
848         void InternalProcessRequest ()
849         {
850                 _requestValueCollection = this.DeterminePostBackMode();
851
852 #if NET_2_0
853                 if (!IsCrossPagePostBack)
854                         LoadPreviousPageReference ();
855                         
856                 OnPreInit (EventArgs.Empty);
857 #endif
858                 Trace.Write ("aspx.page", "Begin Init");
859                 InitRecursive (null);
860                 Trace.Write ("aspx.page", "End Init");
861
862 #if NET_2_0
863                 OnInitComplete (EventArgs.Empty);
864                 
865                 if (masterPageFile != null) {
866                         Controls.Add (Master);
867                         Master.FillPlaceHolders ();
868                 }
869 #endif
870                         
871                 renderingForm = false;  
872                 if (IsPostBack) {
873                         Trace.Write ("aspx.page", "Begin LoadViewState");
874                         LoadPageViewState ();
875                         Trace.Write ("aspx.page", "End LoadViewState");
876                         Trace.Write ("aspx.page", "Begin ProcessPostData");
877                         ProcessPostData (_requestValueCollection, false);
878                         Trace.Write ("aspx.page", "End ProcessPostData");
879                 }
880                 
881 #if NET_2_0
882                 if (IsCrossPagePostBack)
883                         return;
884
885                 OnPreLoad (EventArgs.Empty);
886 #endif
887
888                 LoadRecursive ();
889                 if (IsPostBack) {
890                         Trace.Write ("aspx.page", "Begin ProcessPostData Second Try");
891                         ProcessPostData (secondPostData, true);
892                         Trace.Write ("aspx.page", "End ProcessPostData Second Try");
893                         Trace.Write ("aspx.page", "Begin Raise ChangedEvents");
894                         RaiseChangedEvents ();
895                         Trace.Write ("aspx.page", "End Raise ChangedEvents");
896                         Trace.Write ("aspx.page", "Begin Raise PostBackEvent");
897                         RaisePostBackEvents ();
898                         Trace.Write ("aspx.page", "End Raise PostBackEvent");
899                 }
900                 
901 #if NET_2_0
902                 OnLoadComplete (EventArgs.Empty);
903
904                 if (IsCallback) {
905                         string result = ProcessCallbackData ();
906                         HtmlTextWriter callbackOutput = new HtmlTextWriter (_context.Response.Output);
907                         callbackOutput.Write (result);
908                         callbackOutput.Flush ();
909                         return;
910                 }
911 #endif
912                 
913                 Trace.Write ("aspx.page", "Begin PreRender");
914                 PreRenderRecursiveInternal ();
915                 Trace.Write ("aspx.page", "End PreRender");
916                 
917 #if NET_2_0
918                 OnPreRenderComplete (EventArgs.Empty);
919 #endif
920
921                 Trace.Write ("aspx.page", "Begin SaveViewState");
922                 SavePageViewState ();
923                 Trace.Write ("aspx.page", "End SaveViewState");
924                 
925 #if NET_2_0
926                 OnSaveStateComplete (EventArgs.Empty);
927 #endif
928                 
929                 //--
930                 Trace.Write ("aspx.page", "Begin Render");
931                 HtmlTextWriter output = new HtmlTextWriter (_context.Response.Output);
932                 RenderControl (output);
933                 Trace.Write ("aspx.page", "End Render");
934                 
935                 RenderTrace (output);
936         }
937
938         private void RenderTrace (HtmlTextWriter output)
939         {
940                 TraceManager traceManager = HttpRuntime.TraceManager;
941
942                 if (Trace.HaveTrace && !Trace.IsEnabled || !Trace.HaveTrace && !traceManager.Enabled)
943                         return;
944                 
945                 Trace.SaveData ();
946
947                 if (!Trace.HaveTrace && traceManager.Enabled && !traceManager.PageOutput) 
948                         return;
949
950                 if (!traceManager.LocalOnly || Context.Request.IsLocal)
951                         Trace.Render (output);
952         }
953         
954         internal void RaisePostBackEvents ()
955         {
956                 if (requiresRaiseEvent != null) {
957                         RaisePostBackEvent (requiresRaiseEvent, null);
958                         return;
959                 }
960
961                 NameValueCollection postdata = _requestValueCollection;
962                 if (postdata == null)
963                         return;
964
965                 string eventTarget = postdata [postEventSourceID];
966                 if (eventTarget == null || eventTarget.Length == 0) {
967                         Validate ();
968                         return;
969                 }
970
971                 IPostBackEventHandler target = FindControl (eventTarget) as IPostBackEventHandler;
972                 if (target == null)
973                         return;
974
975                 string eventArgument = postdata [postEventArgumentID];
976                 RaisePostBackEvent (target, eventArgument);
977         }
978
979         internal void RaiseChangedEvents ()
980         {
981                 if (requiresPostDataChanged == null)
982                         return;
983
984                 foreach (IPostBackDataHandler ipdh in requiresPostDataChanged)
985                         ipdh.RaisePostDataChangedEvent ();
986
987                 requiresPostDataChanged = null;
988         }
989
990         [EditorBrowsable (EditorBrowsableState.Advanced)]
991         protected virtual void RaisePostBackEvent (IPostBackEventHandler sourceControl, string eventArgument)
992         {
993                 sourceControl.RaisePostBackEvent (eventArgument);
994         }
995         
996 #if NET_2_0
997         [Obsolete]
998 #endif
999         [EditorBrowsable (EditorBrowsableState.Advanced)]
1000         public void RegisterArrayDeclaration (string arrayName, string arrayValue)
1001         {
1002                 scriptManager.RegisterArrayDeclaration (arrayName, arrayValue);
1003         }
1004
1005 #if NET_2_0
1006         [Obsolete]
1007 #endif
1008         [EditorBrowsable (EditorBrowsableState.Advanced)]
1009         public virtual void RegisterClientScriptBlock (string key, string script)
1010         {
1011                 scriptManager.RegisterClientScriptBlock (key, script);
1012         }
1013
1014 #if NET_2_0
1015         [Obsolete]
1016 #endif
1017         [EditorBrowsable (EditorBrowsableState.Advanced)]
1018         public virtual void RegisterHiddenField (string hiddenFieldName, string hiddenFieldInitialValue)
1019         {
1020                 scriptManager.RegisterHiddenField (hiddenFieldName, hiddenFieldInitialValue);
1021         }
1022
1023         [MonoTODO("Used in HtmlForm")]
1024         internal void RegisterClientScriptFile (string a, string b, string c)
1025         {
1026                 throw new NotImplementedException ();
1027         }
1028
1029 #if NET_2_0
1030         [Obsolete]
1031 #endif
1032         [EditorBrowsable (EditorBrowsableState.Advanced)]
1033         public void RegisterOnSubmitStatement (string key, string script)
1034         {
1035                 scriptManager.RegisterOnSubmitStatement (key, script);
1036         }
1037
1038         [EditorBrowsable (EditorBrowsableState.Advanced)]
1039         public void RegisterRequiresPostBack (Control control)
1040         {
1041                 if (_requiresPostBack == null)
1042                         _requiresPostBack = new ArrayList ();
1043
1044                 _requiresPostBack.Add (control.UniqueID);
1045         }
1046
1047         [EditorBrowsable (EditorBrowsableState.Advanced)]
1048         public virtual void RegisterRequiresRaiseEvent (IPostBackEventHandler control)
1049         {
1050                 requiresRaiseEvent = control;
1051         }
1052
1053 #if NET_2_0
1054         [Obsolete]
1055 #endif
1056         [EditorBrowsable (EditorBrowsableState.Advanced)]
1057         public virtual void RegisterStartupScript (string key, string script)
1058         {
1059                 scriptManager.RegisterStartupScript (key, script);
1060         }
1061
1062         [EditorBrowsable (EditorBrowsableState.Advanced)]
1063         public void RegisterViewStateHandler ()
1064         {
1065                 handleViewState = true;
1066         }
1067
1068         [EditorBrowsable (EditorBrowsableState.Advanced)]
1069         protected virtual void SavePageStateToPersistenceMedium (object viewState)
1070         {
1071                 _savedViewState = viewState;
1072         }
1073
1074         [EditorBrowsable (EditorBrowsableState.Advanced)]
1075         protected virtual object LoadPageStateFromPersistenceMedium ()
1076         {
1077                 NameValueCollection postdata = _requestValueCollection;
1078                 string view_state;
1079                 if (postdata == null || (view_state = postdata ["__VIEWSTATE"]) == null)
1080                         return null;
1081
1082                 _savedViewState = null;
1083                 LosFormatter fmt = new LosFormatter ();
1084
1085                 try { 
1086                         _savedViewState = fmt.Deserialize (view_state);
1087                 } catch (Exception e) {
1088                         throw new HttpException ("Error restoring page viewstate.\n", e);
1089                 }
1090
1091                 return _savedViewState;
1092         }
1093
1094         internal void LoadPageViewState()
1095         {
1096                 object sState = LoadPageStateFromPersistenceMedium ();
1097                 if (sState != null) {
1098 #if NET_2_0
1099                         Triplet data = (Triplet) sState;
1100                         LoadPageControlState (data.Third);
1101                         LoadViewStateRecursive (data.First);
1102                         _requiresPostBack = data.Second as ArrayList;
1103 #else
1104                         Pair pair = (Pair) sState;
1105                         LoadViewStateRecursive (pair.First);
1106                         _requiresPostBack = pair.Second as ArrayList;
1107 #endif
1108                 }
1109         }
1110
1111         internal void SavePageViewState ()
1112         {
1113                 if (!handleViewState)
1114                         return;
1115
1116 #if NET_2_0
1117                 object controlState = SavePageControlState ();
1118 #endif
1119
1120                 object viewState = SaveViewStateRecursive ();
1121                 object reqPostback = (_requiresPostBack != null && _requiresPostBack.Count > 0) ? _requiresPostBack : null;
1122
1123 #if NET_2_0
1124                 Triplet triplet = new Triplet ();
1125                 triplet.First = viewState;
1126                 triplet.Second = reqPostback;
1127                 triplet.Third = controlState;
1128
1129                 if (triplet.First == null && triplet.Second == null && triplet.Third == null)
1130                         triplet = null;
1131                         
1132                 SavePageStateToPersistenceMedium (triplet);
1133 #else
1134                 Pair pair = new Pair ();
1135                 pair.First = viewState;
1136                 pair.Second = reqPostback;
1137
1138                 if (pair.First == null && pair.Second == null)
1139                         pair = null;
1140                         
1141                 SavePageStateToPersistenceMedium (pair);
1142 #endif
1143         }
1144
1145         public virtual void Validate ()
1146         {
1147                 ValidateCollection (_validators);
1148         }
1149         
1150         void ValidateCollection (ValidatorCollection validators)
1151         {
1152                 if (validators == null || validators.Count == 0){
1153                         _isValid = true;
1154                         return;
1155                 }
1156
1157                 bool all_valid = true;
1158                 foreach (IValidator v in validators){
1159                         v.Validate ();
1160                         if (v.IsValid == false)
1161                                 all_valid = false;
1162                 }
1163
1164                 if (all_valid)
1165                         _isValid = true;
1166         }
1167
1168         [EditorBrowsable (EditorBrowsableState.Advanced)]
1169         public virtual void VerifyRenderingInServerForm (Control control)
1170         {
1171                 if (!renderingForm)
1172                         throw new HttpException ("Control '" + control.ClientID + " " + control.GetType () + 
1173                                                  "' must be rendered within a HtmlForm");
1174         }
1175         
1176         #endregion
1177         
1178         #if NET_2_0
1179         public
1180         #else
1181         internal
1182         #endif
1183                 ClientScriptManager ClientScript {
1184                 get { return scriptManager; }
1185         }
1186         
1187         #if NET_2_0
1188         
1189         static readonly object InitCompleteEvent = new object ();
1190         static readonly object LoadCompleteEvent = new object ();
1191         static readonly object PreInitEvent = new object ();
1192         static readonly object PreLoadEvent = new object ();
1193         static readonly object PreRenderCompleteEvent = new object ();
1194         static readonly object SaveStateCompleteEvent = new object ();
1195         
1196         public event EventHandler InitComplete {
1197                 add { Events.AddHandler (InitCompleteEvent, value); }
1198                 remove { Events.RemoveHandler (InitCompleteEvent, value); }
1199         }
1200         
1201         public event EventHandler LoadComplete {
1202                 add { Events.AddHandler (LoadCompleteEvent, value); }
1203                 remove { Events.RemoveHandler (LoadCompleteEvent, value); }
1204         }
1205         
1206         public event EventHandler PreInit {
1207                 add { Events.AddHandler (PreInitEvent, value); }
1208                 remove { Events.RemoveHandler (PreInitEvent, value); }
1209         }
1210         
1211         public event EventHandler PreLoad {
1212                 add { Events.AddHandler (PreLoadEvent, value); }
1213                 remove { Events.RemoveHandler (PreLoadEvent, value); }
1214         }
1215         
1216         public event EventHandler PreRenderComplete {
1217                 add { Events.AddHandler (PreRenderCompleteEvent, value); }
1218                 remove { Events.RemoveHandler (PreRenderCompleteEvent, value); }
1219         }
1220         
1221         public event EventHandler SaveStateComplete {
1222                 add { Events.AddHandler (SaveStateCompleteEvent, value); }
1223                 remove { Events.RemoveHandler (SaveStateCompleteEvent, value); }
1224         }
1225         
1226         protected virtual void OnInitComplete (EventArgs e)
1227         {
1228                 if (Events != null) {
1229                         EventHandler eh = (EventHandler) (Events [InitCompleteEvent]);
1230                         if (eh != null) eh (this, e);
1231                 }
1232         }
1233         
1234         protected virtual void OnLoadComplete (EventArgs e)
1235         {
1236                 if (Events != null) {
1237                         EventHandler eh = (EventHandler) (Events [LoadCompleteEvent]);
1238                         if (eh != null) eh (this, e);
1239                 }
1240         }
1241         
1242         protected virtual void OnPreInit (EventArgs e)
1243         {
1244                 if (Events != null) {
1245                         EventHandler eh = (EventHandler) (Events [PreInitEvent]);
1246                         if (eh != null) eh (this, e);
1247                 }
1248         }
1249         
1250         protected virtual void OnPreLoad (EventArgs e)
1251         {
1252                 if (Events != null) {
1253                         EventHandler eh = (EventHandler) (Events [PreLoadEvent]);
1254                         if (eh != null) eh (this, e);
1255                 }
1256         }
1257         
1258         protected virtual void OnPreRenderComplete (EventArgs e)
1259         {
1260                 if (Events != null) {
1261                         EventHandler eh = (EventHandler) (Events [PreRenderCompleteEvent]);
1262                         if (eh != null) eh (this, e);
1263                 }
1264         }
1265         
1266         protected virtual void OnSaveStateComplete (EventArgs e)
1267         {
1268                 if (Events != null) {
1269                         EventHandler eh = (EventHandler) (Events [SaveStateCompleteEvent]);
1270                         if (eh != null) eh (this, e);
1271                 }
1272         }
1273         
1274         public HtmlForm Form {
1275                 get { return _form; }
1276         }
1277         
1278         internal void RegisterForm (HtmlForm form)
1279         {
1280                 _form = form;
1281         }
1282         
1283     [BrowsableAttribute (false)]
1284     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
1285         public Page PreviousPage {
1286                 get { return previousPage; }
1287         }
1288
1289         
1290     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
1291     [BrowsableAttribute (false)]
1292         public bool IsCallback {
1293                 get { return _requestValueCollection != null && _requestValueCollection [CallbackArgumentID] != null; }
1294         }
1295         
1296     [BrowsableAttribute (false)]
1297     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
1298         public bool IsCrossPagePostBack {
1299                 get { return _requestValueCollection != null && isCrossPagePostBack; }
1300         }
1301         
1302         string ProcessCallbackData ()
1303         {
1304                 string callbackTarget = _requestValueCollection [CallbackSourceID];
1305                 if (callbackTarget == null || callbackTarget.Length == 0)
1306                         throw new HttpException ("Callback target not provided.");
1307
1308                 ICallbackEventHandler target = FindControl (callbackTarget) as ICallbackEventHandler;
1309                 if (target == null)
1310                         throw new HttpException (string.Format ("Invalid callback target '{0}'.", callbackTarget));
1311
1312                 string callbackArgument = _requestValueCollection [CallbackArgumentID];
1313                 return target.RaiseCallbackEvent (callbackArgument);
1314         }
1315
1316     [BrowsableAttribute (false)]
1317     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
1318         public IPageHeader Header {
1319                 get { return htmlHeader; }
1320         }
1321         
1322         internal void SetHeader (IPageHeader header)
1323         {
1324                 htmlHeader = header;
1325         }
1326         
1327     [DefaultValueAttribute ("")]
1328         public string MasterPageFile {
1329                 get { return masterPageFile; }
1330                 set { masterPageFile = value; masterPage = null; }
1331         }
1332         
1333     [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
1334     [BrowsableAttribute (false)]
1335         public MasterPage Master {
1336                 get {
1337                         if (masterPage == null)
1338                                 masterPage = MasterPageParser.GetCompiledMasterInstance (masterPageFile, Server.MapPath (masterPageFile), Context);
1339                         return masterPage;
1340                 }
1341         }
1342         
1343         [EditorBrowsable (EditorBrowsableState.Advanced)]
1344         public void RegisterRequiresControlState (Control control)
1345         {
1346                 if (requireStateControls == null) requireStateControls = new ArrayList ();
1347                 requireStateControls.Add (control);
1348         }
1349         
1350         public bool RequiresControlState (Control control)
1351         {
1352                 if (requireStateControls == null) return false;
1353                 return requireStateControls.Contains (control);
1354         }
1355         
1356         [EditorBrowsable (EditorBrowsableState.Advanced)]
1357         public void UnregisterRequiresControlState (Control control)
1358         {
1359                 if (requireStateControls != null)
1360                         requireStateControls.Remove (control);
1361         }
1362         
1363         public ValidatorCollection GetValidators (string validationGroup)
1364         {
1365                 if (validationGroup == null || validationGroup == "")
1366                         return Validators;
1367
1368                 if (_validatorsByGroup == null) _validatorsByGroup = new Hashtable ();
1369                 ValidatorCollection col = _validatorsByGroup [validationGroup] as ValidatorCollection;
1370                 if (col == null) {
1371                         col = new ValidatorCollection ();
1372                         _validatorsByGroup [validationGroup] = col;
1373                 }
1374                 return col;
1375         }
1376         
1377         public virtual void Validate (string validationGroup)
1378         {
1379                 if (validationGroup == null || validationGroup == "")
1380                         ValidateCollection (_validators);
1381                 else {
1382                         if (_validatorsByGroup != null) {
1383                                 ValidateCollection (_validatorsByGroup [validationGroup] as ValidatorCollection);
1384                         } else {
1385                                 _isValid = true;
1386                         }
1387                 }
1388         }
1389         
1390         object SavePageControlState ()
1391         {
1392                 if (requireStateControls == null) return null;
1393                 object[] state = new object [requireStateControls.Count];
1394                 
1395                 bool allNull = true;
1396                 for (int n=0; n<state.Length; n++) {
1397                         state [n] = ((Control) requireStateControls [n]).SaveControlState ();
1398                         if (state [n] != null) allNull = false;
1399                 }
1400                 if (allNull) return null;
1401                 else return state;
1402         }
1403         
1404         void LoadPageControlState (object data)
1405         {
1406                 if (requireStateControls == null) return;
1407
1408                 object[] state = (object[]) data;
1409                 int max = Math.Min (requireStateControls.Count, state != null ? state.Length : requireStateControls.Count);
1410                 for (int n=0; n < max; n++) {
1411                         Control ctl = (Control) requireStateControls [n];
1412                         ctl.LoadControlState (state != null ? state [n] : null);
1413                 }
1414         }
1415
1416         void LoadPreviousPageReference ()
1417         {
1418                 if (_requestValueCollection != null) {
1419                         string prevPage = _requestValueCollection [PreviousPageID];
1420                         if (prevPage != null) {
1421                                 previousPage = (Page) PageParser.GetCompiledPageInstance (prevPage, Server.MapPath (prevPage), Context);
1422                                 previousPage.ProcessCrossPagePostBack (_context);
1423                         } else {
1424                                 previousPage = _context.LastPage;
1425                         }
1426                 }
1427                 _context.LastPage = this;
1428         }
1429
1430
1431         protected internal void AddContentTemplate (string templateName, ITemplate template)
1432         {
1433                 Master.AddContentTemplate (templateName, template);
1434         }
1435                 
1436         #endif
1437 }
1438 }