Page.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  1. //
  2. // System.Web.UI.Page
  3. //
  4. // Authors:
  5. // Duncan Mak ([email protected])
  6. // Gonzalo Paniagua ([email protected])
  7. //
  8. // (C) 2002 Ximian, Inc. (http://www.ximian.com)
  9. //
  10. using System;
  11. using System.Collections;
  12. using System.Collections.Specialized;
  13. using System.IO;
  14. using System.Reflection;
  15. using System.Security.Principal;
  16. using System.Text;
  17. using System.Web;
  18. using System.Web.Caching;
  19. using System.Web.SessionState;
  20. using System.Web.Util;
  21. namespace System.Web.UI
  22. {
  23. public class Page : TemplateControl, IHttpHandler
  24. {
  25. private string _culture;
  26. private bool _viewState = true;
  27. private bool _viewStateMac = false;
  28. private string _errorPage;
  29. private ArrayList _fileDependencies;
  30. private string _ID;
  31. private bool _isValid;
  32. private HttpServerUtility _server;
  33. private bool _smartNavigation = false;
  34. private TraceContext _trace;
  35. private bool _traceEnabled;
  36. private TraceMode _traceModeValue;
  37. private int _transactionMode;
  38. private string _UICulture;
  39. private HttpContext _context;
  40. private ValidatorCollection _validators;
  41. private bool renderingForm;
  42. private object _savedViewState;
  43. private ArrayList _requiresPostBack;
  44. private ArrayList requiresPostDataChanged;
  45. private ArrayList requiresRaiseEvent;
  46. private NameValueCollection secondPostData;
  47. private bool requiresPostBackScript = false;
  48. private bool postBackScriptRendered = false;
  49. #region Fields
  50. protected const string postEventArgumentID = ""; //FIXME
  51. protected const string postEventSourceID = "";
  52. #endregion
  53. #region Constructor
  54. public Page ()
  55. {
  56. Page = this;
  57. }
  58. #endregion
  59. #region Properties
  60. public HttpApplicationState Application
  61. {
  62. get { return _context.Application; }
  63. }
  64. bool AspCompatMode
  65. {
  66. set { throw new NotImplementedException (); }
  67. }
  68. bool Buffer
  69. {
  70. set { Response.BufferOutput = value; }
  71. }
  72. public Cache Cache
  73. {
  74. get { return _context.Cache; }
  75. }
  76. [MonoTODO]
  77. public string ClientTarget
  78. {
  79. get { throw new NotImplementedException (); }
  80. set { throw new NotImplementedException (); }
  81. }
  82. [MonoTODO]
  83. int CodePage
  84. {
  85. set { throw new NotImplementedException (); }
  86. }
  87. [MonoTODO]
  88. string ContentType
  89. {
  90. set { throw new NotImplementedException (); }
  91. }
  92. protected override HttpContext Context
  93. {
  94. get { return _context; }
  95. }
  96. string Culture
  97. {
  98. set { _culture = value; }
  99. }
  100. public override bool EnableViewState
  101. {
  102. get { return _viewState; }
  103. set { _viewState = value; }
  104. }
  105. protected bool EnableViewStateMac
  106. {
  107. get { return _viewStateMac; }
  108. set { _viewStateMac = value; }
  109. }
  110. public string ErrorPage
  111. {
  112. get { return _errorPage; }
  113. set { _errorPage = value; }
  114. }
  115. ArrayList FileDependencies
  116. {
  117. set { _fileDependencies = value; }
  118. }
  119. public override string ID
  120. {
  121. get { return _ID; }
  122. set { _ID = value; }
  123. }
  124. public bool IsPostBack
  125. {
  126. get {
  127. return (0 == String.Compare (Request.HttpMethod, "POST", true));
  128. }
  129. }
  130. [MonoTODO]
  131. public bool IsReusable
  132. {
  133. get { throw new NotImplementedException (); }
  134. }
  135. public bool IsValid
  136. {
  137. get { return _isValid; }
  138. }
  139. [MonoTODO]
  140. int LCID {
  141. set { throw new NotImplementedException (); }
  142. }
  143. public HttpRequest Request
  144. {
  145. get { return _context.Request; }
  146. }
  147. public HttpResponse Response
  148. {
  149. get { return _context.Response; }
  150. }
  151. string ResponseEncoding
  152. {
  153. set { Response.ContentEncoding = Encoding.GetEncoding (value); }
  154. }
  155. public HttpServerUtility Server
  156. {
  157. get { return _server; }
  158. }
  159. public virtual HttpSessionState Session
  160. {
  161. get { return _context.Session; }
  162. }
  163. public bool SmartNavigation
  164. {
  165. get { return _smartNavigation; }
  166. set { _smartNavigation = value; }
  167. }
  168. public TraceContext Trace
  169. {
  170. get { return _trace; }
  171. }
  172. bool TraceEnabled
  173. {
  174. set { _traceEnabled = value; }
  175. }
  176. TraceMode TraceModeValue
  177. {
  178. set { _traceModeValue = value; }
  179. }
  180. int TransactionMode
  181. {
  182. set { _transactionMode = value; }
  183. }
  184. string UICulture
  185. {
  186. set { _UICulture = value; }
  187. }
  188. public IPrincipal User
  189. {
  190. get { return _context.User; }
  191. }
  192. public ValidatorCollection Validators
  193. {
  194. get {
  195. if (_validators == null)
  196. _validators = new ValidatorCollection ();
  197. return _validators;
  198. }
  199. }
  200. public override bool Visible
  201. {
  202. get { return base.Visible; }
  203. set { base.Visible = value; }
  204. }
  205. #endregion
  206. #region Methods
  207. [MonoTODO]
  208. protected IAsyncResult AspCompatBeginProcessRequest (HttpContext context,
  209. AsyncCallback cb,
  210. object extraData)
  211. {
  212. throw new NotImplementedException ();
  213. }
  214. [MonoTODO]
  215. protected void AspcompatEndProcessRequest (IAsyncResult result)
  216. {
  217. throw new NotImplementedException ();
  218. }
  219. protected virtual HtmlTextWriter CreateHtmlTextWriter (TextWriter tw)
  220. {
  221. return new HtmlTextWriter (tw);
  222. }
  223. [MonoTODO]
  224. public void DesignerInitialize ()
  225. {
  226. throw new NotImplementedException ();
  227. }
  228. protected virtual NameValueCollection DeterminePostBackMode ()
  229. {
  230. if (_context == null)
  231. return null;
  232. HttpRequest req = _context.Request;
  233. if (req == null)
  234. return null;
  235. NameValueCollection coll = null;
  236. if (IsPostBack)
  237. //coll = _context.Request.Form; FIXME: the correct is this one. commented out to let xsp work
  238. coll = _context.Request.QueryString;
  239. else
  240. coll = _context.Request.QueryString;
  241. if (coll == null || coll ["__VIEWSTATE"] == null)
  242. return null;
  243. return coll;
  244. }
  245. [MonoTODO]
  246. public string GetPostBackClientEvent (Control control, string argument)
  247. {
  248. // Don't throw the exception. keep going
  249. //throw new NotImplementedException ();
  250. StringBuilder result = new StringBuilder ();
  251. result.AppendFormat ("GetPostBackClientEvent ('{0}', '{1}')", control.ID, argument);
  252. return result.ToString ();
  253. }
  254. public string GetPostBackClientHyperlink (Control control, string argument)
  255. {
  256. return "javascript:" + GetPostBackEventReference (control, argument);
  257. }
  258. public string GetPostBackEventReference (Control control)
  259. {
  260. return GetPostBackEventReference (control, "");
  261. }
  262. public string GetPostBackEventReference (Control control, string argument)
  263. {
  264. RequiresPostBackScript ();
  265. return String.Format ("__doPostBack ('{0}', '{1}')", control.ID, argument);
  266. }
  267. internal void RequiresPostBackScript ()
  268. {
  269. requiresPostBackScript = true;
  270. }
  271. public virtual int GetTypeHashCode ()
  272. {
  273. return GetHashCode ();
  274. }
  275. [MonoTODO]
  276. protected virtual void InitOutputCache (int duration,
  277. string varyByHeader,
  278. string varyByCustom,
  279. OutputCacheLocation location,
  280. string varyByParam)
  281. {
  282. throw new NotImplementedException ();
  283. }
  284. [MonoTODO]
  285. public bool IsClientScriptBlockRegistered (string key)
  286. {
  287. throw new NotImplementedException ();
  288. }
  289. [MonoTODO]
  290. public bool IsStartupScriptRegistered (string key)
  291. {
  292. throw new NotImplementedException ();
  293. }
  294. [MonoTODO]
  295. public string MapPath (string virtualPath)
  296. {
  297. throw new NotImplementedException ();
  298. }
  299. MethodInfo [] autoEventsMethods = null;
  300. private void InvokeEventMethod (string m_name, object sender, EventArgs e)
  301. {
  302. if (autoEventsMethods == null) {
  303. BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic |
  304. BindingFlags.DeclaredOnly | BindingFlags.Instance;
  305. MethodInfo [] m1 = GetType ().GetMethods (bf);
  306. bf = BindingFlags.Public | BindingFlags.NonPublic |
  307. BindingFlags.DeclaredOnly | BindingFlags.Static;
  308. MethodInfo [] m2 = GetType ().GetMethods (bf);
  309. autoEventsMethods = new MethodInfo [m1.Length + m2.Length];
  310. m1.CopyTo (autoEventsMethods, 0);
  311. m2.CopyTo (autoEventsMethods, m1.Length);
  312. }
  313. foreach (MethodInfo m in autoEventsMethods) {
  314. if (m.ReturnType != typeof (void))
  315. continue;
  316. if (m.Name != m_name)
  317. continue;
  318. ParameterInfo [] pi = m.GetParameters ();
  319. if (pi.Length != 2)
  320. continue;
  321. if (pi [0].ParameterType != typeof (object) ||
  322. pi [1].ParameterType != typeof (EventArgs))
  323. continue;
  324. object [] parms = new object [2];
  325. parms [0] = sender;
  326. parms [1] = e;
  327. m.Invoke (this, parms);
  328. break;
  329. }
  330. }
  331. private void RenderPostBackScript (HtmlTextWriter writer, string formUniqueID)
  332. {
  333. writer.WriteLine ("<input type=\"hidden\" name=\"__EVENTTARGET\" value=\"\" />");
  334. writer.WriteLine ("<input type=\"hidden\" name=\"__EVENTARGUMENT\" value=\"\" />");
  335. writer.WriteLine ();
  336. writer.WriteLine ("<script language=\"javascript\">");
  337. writer.WriteLine ("<!--");
  338. writer.WriteLine ("\tfunction __doPostBack(eventTarget, eventArgument) {");
  339. writer.WriteLine ("\t\tvar theform = document.{0};", formUniqueID);
  340. writer.WriteLine ("\t\ttheform.__EVENTTARGET.value = eventTarget;");
  341. writer.WriteLine ("\t\ttheform.__EVENTARGUMENT.value = eventArgument;");
  342. writer.WriteLine ("\t\ttheform.submit();");
  343. writer.WriteLine ("\t}");
  344. writer.WriteLine ("// -->");
  345. writer.WriteLine ("</script>");
  346. }
  347. private bool got_state = false;
  348. private int _random;
  349. private int queryStringHash;
  350. internal void OnFormRender (HtmlTextWriter writer, string formUniqueID)
  351. {
  352. if (renderingForm)
  353. throw new HttpException ("Only 1 HtmlForm is allowed per page.");
  354. renderingForm = true;
  355. writer.WriteLine ();
  356. writer.Write ("<input type=\"hidden\" name=\"__VIEWSTATE\" ");
  357. writer.WriteLine ("value=\"{0}\" />", GetViewStateString ());
  358. if (requiresPostBackScript) {
  359. RenderPostBackScript (writer, formUniqueID);
  360. postBackScriptRendered = true;
  361. }
  362. }
  363. public string GetViewStateString ()
  364. {
  365. StringBuilder state_string = new StringBuilder ();
  366. state_string.AppendFormat ("{0:X}", GetTypeHashCode ());
  367. state_string.AppendFormat ("{0:X}", queryStringHash);
  368. if (!got_state) {
  369. Random rnd = new Random ();
  370. _random = rnd.Next ();
  371. if (_random < 0)
  372. _random = -_random;
  373. _random++;
  374. got_state = true;
  375. }
  376. state_string.AppendFormat ("{0:X}", _random);
  377. return state_string.ToString ();
  378. }
  379. internal void OnFormPostRender (HtmlTextWriter writer, string formUniqueID)
  380. {
  381. if (!postBackScriptRendered && requiresPostBackScript)
  382. RenderPostBackScript (writer, formUniqueID);
  383. renderingForm = false;
  384. postBackScriptRendered = false;
  385. }
  386. private void _Page_Init (object sender, EventArgs e)
  387. {
  388. InvokeEventMethod ("Page_Init", sender, e);
  389. }
  390. private void _Page_Load (object sender, EventArgs e)
  391. {
  392. InvokeEventMethod ("Page_Load", sender, e);
  393. }
  394. private void _Page_DataBind (object sender, EventArgs e)
  395. {
  396. InvokeEventMethod ("Page_DataBind", sender, e);
  397. }
  398. private void _Page_PreRender (object sender, EventArgs e)
  399. {
  400. InvokeEventMethod ("Page_PreRender", sender, e);
  401. }
  402. private void _Page_Dispose (object sender, EventArgs e)
  403. {
  404. InvokeEventMethod ("Page_Dispose", sender, e);
  405. }
  406. private void _Page_Error (object sender, EventArgs e)
  407. {
  408. InvokeEventMethod ("Page_Error", sender, e);
  409. }
  410. private void ProcessPostData (NameValueCollection data, bool second)
  411. {
  412. if (data == null)
  413. return;
  414. foreach (string id in data.AllKeys){
  415. if (id == "__VIEWSTATE")
  416. continue;
  417. Control ctrl = FindControl (id);
  418. if (ctrl != null){
  419. IPostBackDataHandler pbdh = ctrl as IPostBackDataHandler;
  420. IPostBackEventHandler pbeh = ctrl as IPostBackEventHandler;
  421. if (pbdh == null) {
  422. if (pbeh != null)
  423. RegisterRequiresRaiseEvent (pbeh);
  424. continue;
  425. }
  426. if (pbdh.LoadPostData (id, data) == true) {
  427. if (requiresPostDataChanged == null)
  428. requiresPostDataChanged = new ArrayList ();
  429. requiresPostDataChanged.Add (pbdh);
  430. }
  431. } else if (!second) {
  432. if (secondPostData == null)
  433. secondPostData = new NameValueCollection ();
  434. secondPostData.Add (id, null);
  435. }
  436. }
  437. }
  438. private bool init_done;
  439. public void ProcessRequest (HttpContext context)
  440. {
  441. _context = context;
  442. WebTrace.PushContext ("Page.ProcessRequest ()");
  443. WebTrace.WriteLine ("Entering");
  444. if (!init_done){
  445. init_done = true;
  446. // These should depend on AutoEventWireUp in Page directive. Defaults to true.
  447. Init += new EventHandler (_Page_Init);
  448. Load += new EventHandler (_Page_Load);
  449. DataBinding += new EventHandler (_Page_DataBind);
  450. PreRender += new EventHandler (_Page_PreRender);
  451. Disposed += new EventHandler (_Page_Dispose);
  452. Error += new EventHandler (_Page_Error);
  453. WebTrace.WriteLine ("Finished init");
  454. }
  455. //-- Control execution lifecycle in the docs
  456. WebTrace.WriteLine ("Controls.Clear");
  457. Controls.Clear ();
  458. WebTrace.WriteLine ("FrameworkInitialize");
  459. FrameworkInitialize ();
  460. WebTrace.WriteLine ("InitRecursive");
  461. InitRecursive (null);
  462. got_state = false;
  463. renderingForm = false;
  464. _context = context;
  465. queryStringHash = _context.Request.QueryString.GetHashCode ();
  466. if (IsPostBack) {
  467. LoadPageViewState ();
  468. ProcessPostData (DeterminePostBackMode (), false);
  469. }
  470. WebTrace.WriteLine ("LoadRecursive");
  471. LoadRecursive ();
  472. if (IsPostBack) {
  473. ProcessPostData (secondPostData, true);
  474. RaiseChangedEvents ();
  475. RaisePostBackEvents ();
  476. }
  477. WebTrace.WriteLine ("PreRenderRecursiveInternal");
  478. PreRenderRecursiveInternal ();
  479. WebTrace.WriteLine ("SavePageViewState");
  480. SavePageViewState ();
  481. //--
  482. StringBuilder sb = new StringBuilder ();
  483. StringWriter sr = new StringWriter (sb);
  484. HtmlTextWriter output = new HtmlTextWriter (context.Response.Output);
  485. WebTrace.WriteLine ("RenderControl");
  486. RenderControl (output);
  487. _context = null;
  488. WebTrace.WriteLine ("End");
  489. WebTrace.PopContext ();
  490. }
  491. internal void RaisePostBackEvents ()
  492. {
  493. NameValueCollection postdata = DeterminePostBackMode ();
  494. string eventTarget = postdata ["__EVENTTARGET"];
  495. if (eventTarget != null && eventTarget.Length > 0) {
  496. Control target = FindControl (eventTarget);
  497. if (!(target is IPostBackEventHandler))
  498. return;
  499. string eventArgument = postdata ["__EVENTARGUMENT"];
  500. RaisePostBackEvent ((IPostBackEventHandler) target, eventArgument);
  501. return;
  502. }
  503. if (requiresRaiseEvent == null)
  504. return;
  505. foreach (Control c in requiresRaiseEvent)
  506. RaisePostBackEvent ((IPostBackEventHandler) c, postdata [c.ID]);
  507. requiresRaiseEvent.Clear ();
  508. }
  509. internal void RaiseChangedEvents ()
  510. {
  511. if (requiresPostDataChanged == null)
  512. return;
  513. foreach (IPostBackDataHandler ipdh in requiresPostDataChanged)
  514. ipdh.RaisePostDataChangedEvent ();
  515. requiresPostDataChanged.Clear ();
  516. }
  517. protected virtual void RaisePostBackEvent (IPostBackEventHandler sourceControl, string eventArgument)
  518. {
  519. sourceControl.RaisePostBackEvent (eventArgument);
  520. }
  521. [MonoTODO]
  522. public void RegisterArrayDeclaration (string arrayName, string arrayValue)
  523. {
  524. throw new NotImplementedException ();
  525. }
  526. [MonoTODO]
  527. public virtual void RegisterClientScriptBlock (string key, string script)
  528. {
  529. throw new NotImplementedException ();
  530. }
  531. [MonoTODO]
  532. public virtual void RegisterHiddenField (string hiddenFieldName, string hiddenFieldInitialValue)
  533. {
  534. throw new NotImplementedException ();
  535. }
  536. [MonoTODO]
  537. public void RegisterClientScriptFile (string a, string b, string c)
  538. {
  539. throw new NotImplementedException ();
  540. }
  541. [MonoTODO]
  542. public void RegisterOnSubmitStatement (string key, string script)
  543. {
  544. throw new NotImplementedException ();
  545. }
  546. public void RegisterRequiresPostBack (Control control)
  547. {
  548. if (_requiresPostBack == null)
  549. _requiresPostBack = new ArrayList ();
  550. _requiresPostBack.Add (control);
  551. }
  552. public virtual void RegisterRequiresRaiseEvent (IPostBackEventHandler control)
  553. {
  554. if (requiresRaiseEvent == null)
  555. requiresRaiseEvent = new ArrayList ();
  556. requiresRaiseEvent.Add (control);
  557. }
  558. [MonoTODO]
  559. public void RegisterViewStateHandler ()
  560. {
  561. // Do nothing
  562. }
  563. protected virtual void SavePageStateToPersistenceMedium (object viewState)
  564. {
  565. _savedViewState = viewState;
  566. }
  567. protected virtual object LoadPageStateFromPersistenceMedium ()
  568. {
  569. return _savedViewState;
  570. }
  571. internal void LoadPageViewState()
  572. {
  573. object sState = LoadPageStateFromPersistenceMedium ();
  574. if (sState != null) {
  575. Pair pair = (Pair) sState;
  576. LoadViewStateRecursive (pair.First);
  577. _requiresPostBack = pair.Second as ArrayList;
  578. }
  579. }
  580. internal void SavePageViewState ()
  581. {
  582. Pair pair = new Pair ();
  583. pair.First = SaveViewStateRecursive ();
  584. pair.Second = _requiresPostBack;
  585. SavePageStateToPersistenceMedium (pair);
  586. }
  587. public virtual void Validate ()
  588. {
  589. if (_validators == null || _validators.Count == 0){
  590. _isValid = true;
  591. return;
  592. }
  593. bool all_valid = true;
  594. foreach (IValidator v in _validators){
  595. v.Validate ();
  596. if (v.IsValid == false)
  597. all_valid = false;
  598. }
  599. if (all_valid)
  600. _isValid = true;
  601. }
  602. public virtual void VerifyRenderingInServerForm (Control control)
  603. {
  604. if (!renderingForm)
  605. throw new HttpException ("Control '" + control.ClientID + " " + control.GetType () +
  606. "' must be rendered within a HtmlForm");
  607. }
  608. #endregion
  609. }
  610. }