ObjectDataSourceView.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053
  1. //
  2. // System.Web.UI.WebControls.ObjectDataSourceView
  3. //
  4. // Authors:
  5. // Lluis Sanchez Gual ([email protected])
  6. //
  7. // (C) 2005 Novell, Inc. (http://www.novell.com)
  8. //
  9. //
  10. // Permission is hereby granted, free of charge, to any person obtaining
  11. // a copy of this software and associated documentation files (the
  12. // "Software"), to deal in the Software without restriction, including
  13. // without limitation the rights to use, copy, modify, merge, publish,
  14. // distribute, sublicense, and/or sell copies of the Software, and to
  15. // permit persons to whom the Software is furnished to do so, subject to
  16. // the following conditions:
  17. //
  18. // The above copyright notice and this permission notice shall be
  19. // included in all copies or substantial portions of the Software.
  20. //
  21. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  25. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  26. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  27. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  28. //
  29. #if NET_2_0
  30. using System;
  31. using System.Reflection;
  32. using System.Collections;
  33. using System.Collections.Specialized;
  34. using System.ComponentModel;
  35. using System.IO;
  36. using System.Data;
  37. namespace System.Web.UI.WebControls
  38. {
  39. public class ObjectDataSourceView : DataSourceView, IStateManager
  40. {
  41. ObjectDataSource owner;
  42. HttpContext context;
  43. Type objectType;
  44. Type dataObjectType;
  45. StateBag viewState = new StateBag ();
  46. ParameterCollection selectParameters;
  47. ParameterCollection updateParameters;
  48. ParameterCollection deleteParameters;
  49. ParameterCollection insertParameters;
  50. ParameterCollection filterParameters;
  51. private static readonly object DeletedEvent = new object();
  52. private static readonly object DeletingEvent = new object();
  53. private static readonly object FilteringEvent = new object();
  54. private static readonly object InsertedEvent = new object();
  55. private static readonly object InsertingEvent = new object();
  56. private static readonly object ObjectCreatedEvent = new object();
  57. private static readonly object ObjectCreatingEvent = new object();
  58. private static readonly object ObjectDisposingEvent = new object();
  59. // private static readonly object ResolvingMethodEvent = new object();
  60. private static readonly object SelectedEvent = new object();
  61. private static readonly object SelectingEvent = new object();
  62. private static readonly object UpdatedEvent = new object();
  63. private static readonly object UpdatingEvent = new object();
  64. public ObjectDataSourceView (ObjectDataSource owner, string name, HttpContext context): base (owner, name)
  65. {
  66. this.owner = owner;
  67. this.context = context;
  68. }
  69. public event ObjectDataSourceStatusEventHandler Deleted {
  70. add { Events.AddHandler (DeletedEvent, value); }
  71. remove { Events.RemoveHandler (DeletedEvent, value); }
  72. }
  73. public event ObjectDataSourceMethodEventHandler Deleting {
  74. add { Events.AddHandler (DeletingEvent, value); }
  75. remove { Events.RemoveHandler (DeletingEvent, value); }
  76. }
  77. public event ObjectDataSourceFilteringEventHandler Filtering {
  78. add { Events.AddHandler (FilteringEvent, value); }
  79. remove { Events.RemoveHandler (FilteringEvent, value); }
  80. }
  81. public event ObjectDataSourceStatusEventHandler Inserted {
  82. add { Events.AddHandler (InsertedEvent, value); }
  83. remove { Events.RemoveHandler (InsertedEvent, value); }
  84. }
  85. public event ObjectDataSourceMethodEventHandler Inserting {
  86. add { Events.AddHandler (InsertingEvent, value); }
  87. remove { Events.RemoveHandler (InsertingEvent, value); }
  88. }
  89. public event ObjectDataSourceObjectEventHandler ObjectCreated {
  90. add { Events.AddHandler (ObjectCreatedEvent, value); }
  91. remove { Events.RemoveHandler (ObjectCreatedEvent, value); }
  92. }
  93. public event ObjectDataSourceObjectEventHandler ObjectCreating {
  94. add { Events.AddHandler (ObjectCreatingEvent, value); }
  95. remove { Events.RemoveHandler (ObjectCreatingEvent, value); }
  96. }
  97. public event ObjectDataSourceDisposingEventHandler ObjectDisposing {
  98. add { Events.AddHandler (ObjectDisposingEvent, value); }
  99. remove { Events.RemoveHandler (ObjectDisposingEvent, value); }
  100. }
  101. /* public event ObjectDataSourceResolvingMethodEventHandler ResolvingMethod {
  102. add { Events.AddHandler (ResolvingMethodEvent, value); }
  103. remove { Events.RemoveHandler (ResolvingMethodEvent, value); }
  104. }
  105. */
  106. public event ObjectDataSourceStatusEventHandler Selected {
  107. add { Events.AddHandler (SelectedEvent, value); }
  108. remove { Events.RemoveHandler (SelectedEvent, value); }
  109. }
  110. public event ObjectDataSourceSelectingEventHandler Selecting {
  111. add { Events.AddHandler (SelectingEvent, value); }
  112. remove { Events.RemoveHandler (SelectingEvent, value); }
  113. }
  114. public event ObjectDataSourceStatusEventHandler Updated {
  115. add { Events.AddHandler (UpdatedEvent, value); }
  116. remove { Events.RemoveHandler (UpdatedEvent, value); }
  117. }
  118. public event ObjectDataSourceMethodEventHandler Updating {
  119. add { Events.AddHandler (UpdatingEvent, value); }
  120. remove { Events.RemoveHandler (UpdatingEvent, value); }
  121. }
  122. protected virtual void OnDeleted (ObjectDataSourceStatusEventArgs e)
  123. {
  124. if (Events != null) {
  125. ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [DeletedEvent];
  126. if (eh != null) eh (this, e);
  127. }
  128. }
  129. protected virtual void OnDeleting (ObjectDataSourceMethodEventArgs e)
  130. {
  131. if (Events != null) {
  132. ObjectDataSourceMethodEventHandler eh = (ObjectDataSourceMethodEventHandler) Events [DeletingEvent];
  133. if (eh != null) eh (this, e);
  134. }
  135. }
  136. protected virtual void OnFiltering (ObjectDataSourceFilteringEventArgs e)
  137. {
  138. if (Events != null) {
  139. ObjectDataSourceFilteringEventHandler eh = (ObjectDataSourceFilteringEventHandler) Events [FilteringEvent];
  140. if (eh != null) eh (this, e);
  141. }
  142. }
  143. protected virtual void OnInserted (ObjectDataSourceStatusEventArgs e)
  144. {
  145. if (Events != null) {
  146. ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [InsertedEvent];
  147. if (eh != null) eh (this, e);
  148. }
  149. }
  150. protected virtual void OnInserting (ObjectDataSourceMethodEventArgs e)
  151. {
  152. if (Events != null) {
  153. ObjectDataSourceMethodEventHandler eh = (ObjectDataSourceMethodEventHandler) Events [InsertingEvent];
  154. if (eh != null) eh (this, e);
  155. }
  156. }
  157. protected virtual void OnObjectCreated (ObjectDataSourceEventArgs e)
  158. {
  159. if (Events != null) {
  160. ObjectDataSourceObjectEventHandler eh = (ObjectDataSourceObjectEventHandler) Events [ObjectCreatedEvent];
  161. if (eh != null) eh (this, e);
  162. }
  163. }
  164. protected virtual void OnObjectCreating (ObjectDataSourceEventArgs e)
  165. {
  166. if (Events != null) {
  167. ObjectDataSourceObjectEventHandler eh = (ObjectDataSourceObjectEventHandler) Events [ObjectCreatingEvent];
  168. if (eh != null) eh (this, e);
  169. }
  170. }
  171. protected virtual void OnObjectDisposing (ObjectDataSourceDisposingEventArgs e)
  172. {
  173. if (Events != null) {
  174. ObjectDataSourceDisposingEventHandler eh = (ObjectDataSourceDisposingEventHandler) Events [ObjectDisposingEvent];
  175. if (eh != null) eh (this, e);
  176. }
  177. }
  178. /* protected virtual void OnResolvingMethod (ObjectDataSourceResolvingMethodEventArgs e)
  179. {
  180. if (Events != null) {
  181. ObjectDataSourceResolvingMethodEventHandler eh = (ObjectDataSourceResolvingMethodEventHandler) Events [ResolvingMethodEvent];
  182. if (eh != null) eh (this, e);
  183. }
  184. }
  185. */
  186. protected virtual void OnSelected (ObjectDataSourceStatusEventArgs e)
  187. {
  188. if (Events != null) {
  189. ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [SelectedEvent];
  190. if (eh != null) eh (this, e);
  191. }
  192. }
  193. protected virtual void OnSelecting (ObjectDataSourceSelectingEventArgs e)
  194. {
  195. if (Events != null) {
  196. ObjectDataSourceSelectingEventHandler eh = (ObjectDataSourceSelectingEventHandler) Events [SelectingEvent];
  197. if (eh != null) eh (this, e);
  198. }
  199. }
  200. protected virtual void OnUpdated (ObjectDataSourceStatusEventArgs e)
  201. {
  202. if (Events != null) {
  203. ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [UpdatedEvent];
  204. if (eh != null) eh (this, e);
  205. }
  206. }
  207. protected virtual void OnUpdating (ObjectDataSourceMethodEventArgs e)
  208. {
  209. if (Events != null) {
  210. ObjectDataSourceMethodEventHandler eh = (ObjectDataSourceMethodEventHandler) Events [UpdatingEvent];
  211. if (eh != null) eh (this, e);
  212. }
  213. }
  214. StateBag ViewState {
  215. get { return viewState; }
  216. }
  217. public override bool CanDelete {
  218. get { return DeleteMethod.Length > 0; }
  219. }
  220. public override bool CanInsert {
  221. get { return InsertMethod.Length > 0; }
  222. }
  223. public override bool CanPage {
  224. get { return EnablePaging; }
  225. }
  226. public override bool CanRetrieveTotalRowCount {
  227. get { return SelectCountMethod.Length > 0; }
  228. }
  229. public override bool CanSort {
  230. get { return true; }
  231. }
  232. public override bool CanUpdate {
  233. get { return UpdateMethod.Length > 0; }
  234. }
  235. public ConflictOptions ConflictDetection {
  236. get {
  237. object ret = ViewState ["ConflictDetection"];
  238. return ret != null ? (ConflictOptions)ret : ConflictOptions.OverwriteChanges;
  239. }
  240. set {
  241. ViewState ["ConflictDetection"] = value;
  242. }
  243. }
  244. public bool ConvertNullToDBNull {
  245. get {
  246. object ret = ViewState ["ConvertNullToDBNull"];
  247. return ret != null ? (bool)ret : false;
  248. }
  249. set {
  250. ViewState ["ConvertNullToDBNull"] = value;
  251. }
  252. }
  253. public string DataObjectTypeName {
  254. get {
  255. object ret = ViewState ["DataObjectTypeName"];
  256. return ret != null ? (string)ret : string.Empty;
  257. }
  258. set {
  259. ViewState ["DataObjectTypeName"] = value;
  260. }
  261. }
  262. public string DeleteMethod {
  263. get {
  264. object ret = ViewState ["DeleteMethod"];
  265. return ret != null ? (string)ret : string.Empty;
  266. }
  267. set {
  268. ViewState ["DeleteMethod"] = value;
  269. }
  270. }
  271. public ParameterCollection DeleteParameters {
  272. get {
  273. if (deleteParameters == null) {
  274. deleteParameters = new ParameterCollection ();
  275. deleteParameters.ParametersChanged += new EventHandler (OnParametersChanged);
  276. if (IsTrackingViewState)
  277. ((IStateManager)deleteParameters).TrackViewState ();
  278. }
  279. return deleteParameters;
  280. }
  281. }
  282. public bool EnablePaging {
  283. get {
  284. object ret = ViewState ["EnablePaging"];
  285. return ret != null ? (bool)ret : false;
  286. }
  287. set {
  288. ViewState ["EnablePaging"] = value;
  289. }
  290. }
  291. public string FilterExpression {
  292. get {
  293. object ret = ViewState ["FilterExpression"];
  294. return ret != null ? (string)ret : string.Empty;
  295. }
  296. set {
  297. ViewState ["FilterExpression"] = value;
  298. }
  299. }
  300. public ParameterCollection FilterParameters {
  301. get {
  302. if (filterParameters == null) {
  303. filterParameters = new ParameterCollection ();
  304. filterParameters.ParametersChanged += new EventHandler (OnParametersChanged);
  305. if (IsTrackingViewState)
  306. ((IStateManager)filterParameters).TrackViewState ();
  307. }
  308. return filterParameters;
  309. }
  310. }
  311. public string InsertMethod {
  312. get {
  313. object ret = ViewState ["InsertMethod"];
  314. return ret != null ? (string)ret : string.Empty;
  315. }
  316. set {
  317. ViewState ["InsertMethod"] = value;
  318. }
  319. }
  320. public ParameterCollection InsertParameters {
  321. get {
  322. if (insertParameters == null) {
  323. insertParameters = new ParameterCollection ();
  324. insertParameters.ParametersChanged += new EventHandler (OnParametersChanged);
  325. if (IsTrackingViewState)
  326. ((IStateManager)insertParameters).TrackViewState ();
  327. }
  328. return insertParameters;
  329. }
  330. }
  331. public string MaximumRowsParameterName {
  332. get {
  333. object ret = ViewState ["MaximumRowsParameterName"];
  334. return ret != null ? (string)ret : "maximumRows";
  335. }
  336. set {
  337. ViewState ["MaximumRowsParameterName"] = value;
  338. }
  339. }
  340. [DefaultValueAttribute ("{0}")]
  341. public string OldValuesParameterFormatString {
  342. get {
  343. object ret = ViewState ["OldValuesParameterFormatString"];
  344. return ret != null ? (string)ret : "{0}";
  345. }
  346. set {
  347. ViewState ["OldValuesParameterFormatString"] = value;
  348. }
  349. }
  350. public string SelectCountMethod {
  351. get {
  352. object ret = ViewState ["SelectCountMethod"];
  353. return ret != null ? (string)ret : string.Empty;
  354. }
  355. set {
  356. ViewState ["SelectCountMethod"] = value;
  357. }
  358. }
  359. public string SelectMethod {
  360. get {
  361. object ret = ViewState ["SelectMethod"];
  362. return ret != null ? (string)ret : string.Empty;
  363. }
  364. set {
  365. ViewState ["SelectMethod"] = value;
  366. }
  367. }
  368. public ParameterCollection SelectParameters {
  369. get {
  370. if (selectParameters == null) {
  371. selectParameters = new ParameterCollection ();
  372. selectParameters.ParametersChanged += new EventHandler (OnParametersChanged);
  373. if (IsTrackingViewState)
  374. ((IStateManager)selectParameters).TrackViewState ();
  375. }
  376. return selectParameters;
  377. }
  378. }
  379. public string SortParameterName {
  380. get {
  381. object ret = ViewState ["SortParameterName"];
  382. return ret != null ? (string)ret : string.Empty;
  383. }
  384. set {
  385. ViewState ["SortParameterName"] = value;
  386. }
  387. }
  388. public string StartRowIndexParameterName {
  389. get {
  390. object ret = ViewState ["StartRowIndexParameterName"];
  391. return ret != null ? (string)ret : "startRowIndex";
  392. }
  393. set {
  394. ViewState ["StartRowIndexParameterName"] = value;
  395. }
  396. }
  397. public string TypeName {
  398. get {
  399. object ret = ViewState ["TypeName"];
  400. return ret != null ? (string)ret : string.Empty;
  401. }
  402. set {
  403. ViewState ["TypeName"] = value;
  404. objectType = null;
  405. }
  406. }
  407. public string UpdateMethod {
  408. get {
  409. object ret = ViewState ["UpdateMethod"];
  410. return ret != null ? (string)ret : string.Empty;
  411. }
  412. set {
  413. ViewState ["UpdateMethod"] = value;
  414. }
  415. }
  416. public ParameterCollection UpdateParameters {
  417. get {
  418. if (updateParameters == null) {
  419. updateParameters = new ParameterCollection ();
  420. updateParameters.ParametersChanged += new EventHandler (OnParametersChanged);
  421. if (IsTrackingViewState)
  422. ((IStateManager)updateParameters).TrackViewState ();
  423. }
  424. return updateParameters;
  425. }
  426. }
  427. Type ObjectType {
  428. get {
  429. if (objectType == null) {
  430. objectType = Type.GetType (TypeName);
  431. if (objectType == null)
  432. throw new InvalidOperationException ("Type not found: " + TypeName);
  433. }
  434. return objectType;
  435. }
  436. }
  437. Type DataObjectType {
  438. get {
  439. if (dataObjectType == null) {
  440. dataObjectType = Type.GetType (DataObjectTypeName);
  441. if (objectType == null)
  442. throw new InvalidOperationException ("Type not found: " + DataObjectTypeName);
  443. }
  444. return dataObjectType;
  445. }
  446. }
  447. public IEnumerable Select (DataSourceSelectArguments arguments)
  448. {
  449. return ExecuteSelect (arguments);
  450. }
  451. public int Update (IDictionary keys, IDictionary values, IDictionary oldValues)
  452. {
  453. return ExecuteUpdate (keys, values, oldValues);
  454. }
  455. public int Delete (IDictionary keys, IDictionary oldValues)
  456. {
  457. return ExecuteDelete (keys, oldValues);
  458. }
  459. public int Insert (IDictionary values)
  460. {
  461. return ExecuteInsert (values);
  462. }
  463. protected override int ExecuteInsert (IDictionary values)
  464. {
  465. if (!CanInsert)
  466. throw new NotSupportedException ("Insert operation not supported.");
  467. IOrderedDictionary paramValues;
  468. MethodInfo method;
  469. if (DataObjectTypeName.Length == 0) {
  470. paramValues = MergeParameterValues (InsertParameters, values, null, true);
  471. method = GetObjectMethod (InsertMethod, paramValues);
  472. } else {
  473. method = ResolveDataObjectMethod (InsertMethod, values, null, out paramValues);
  474. }
  475. ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
  476. OnInserting (args);
  477. if (args.Cancel)
  478. return -1;
  479. ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
  480. OnInserted (rargs);
  481. if (rargs.Exception != null && !rargs.ExceptionHandled)
  482. throw rargs.Exception;
  483. OnDataSourceViewChanged (EventArgs.Empty);
  484. return -1;
  485. }
  486. protected override int ExecuteDelete (IDictionary keys, IDictionary oldValues)
  487. {
  488. if (!CanDelete)
  489. throw new NotSupportedException ("Delete operation not supported.");
  490. if (ConflictDetection == ConflictOptions.CompareAllValues && (oldValues == null || oldValues.Count == 0))
  491. throw new InvalidOperationException ("ConflictDetection is set to CompareAllValues and oldValues collection is null or empty.");
  492. IDictionary oldDataValues;
  493. if (ConflictDetection == ConflictOptions.CompareAllValues) {
  494. oldDataValues = new Hashtable ();
  495. foreach (DictionaryEntry de in keys)
  496. oldDataValues [de.Key] = de.Value;
  497. foreach (DictionaryEntry de in oldValues)
  498. oldDataValues [de.Key] = de.Value;
  499. } else
  500. oldDataValues = keys;
  501. IOrderedDictionary paramValues;
  502. MethodInfo method;
  503. if (DataObjectTypeName.Length == 0) {
  504. paramValues = MergeParameterValues (DeleteParameters, null, oldDataValues, false);
  505. method = GetObjectMethod (DeleteMethod, paramValues);
  506. } else {
  507. method = ResolveDataObjectMethod (DeleteMethod, oldDataValues, null, out paramValues);
  508. }
  509. ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
  510. OnDeleting (args);
  511. if (args.Cancel)
  512. return -1;
  513. ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
  514. OnDeleted (rargs);
  515. if (rargs.Exception != null && !rargs.ExceptionHandled)
  516. throw rargs.Exception;
  517. OnDataSourceViewChanged (EventArgs.Empty);
  518. return -1;
  519. }
  520. protected override int ExecuteUpdate (IDictionary keys, IDictionary values, IDictionary oldValues)
  521. {
  522. IOrderedDictionary paramValues;
  523. MethodInfo method;
  524. if (DataObjectTypeName.Length == 0)
  525. {
  526. IDictionary dataValues;
  527. IDictionary oldDataValues;
  528. if (ConflictDetection == ConflictOptions.CompareAllValues) {
  529. oldDataValues = new Hashtable ();
  530. dataValues = values;
  531. foreach (DictionaryEntry de in keys)
  532. oldDataValues [de.Key] = de.Value;
  533. foreach (DictionaryEntry de in oldValues)
  534. oldDataValues [de.Key] = de.Value;
  535. } else {
  536. oldDataValues = keys;
  537. dataValues = values;
  538. }
  539. paramValues = MergeParameterValues (UpdateParameters, dataValues, oldDataValues, false);
  540. method = GetObjectMethod (UpdateMethod, paramValues);
  541. }
  542. else
  543. {
  544. IDictionary dataValues = new Hashtable ();
  545. IDictionary oldDataValues;
  546. foreach (DictionaryEntry de in values)
  547. dataValues [de.Key] = de.Value;
  548. if (ConflictDetection == ConflictOptions.CompareAllValues) {
  549. oldDataValues = new Hashtable ();
  550. foreach (DictionaryEntry de in keys) {
  551. oldDataValues [de.Key] = de.Value;
  552. dataValues [de.Key] = de.Value;
  553. }
  554. foreach (DictionaryEntry de in oldValues)
  555. oldDataValues [de.Key] = de.Value;
  556. } else {
  557. oldDataValues = null;
  558. foreach (DictionaryEntry de in keys)
  559. dataValues [de.Key] = de.Value;
  560. }
  561. method = ResolveDataObjectMethod (UpdateMethod, dataValues, oldDataValues, out paramValues);
  562. }
  563. ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
  564. OnUpdating (args);
  565. if (args.Cancel)
  566. return -1;
  567. ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
  568. OnUpdated (rargs);
  569. if (rargs.Exception != null && !rargs.ExceptionHandled)
  570. throw rargs.Exception;
  571. OnDataSourceViewChanged (EventArgs.Empty);
  572. return -1;
  573. }
  574. protected internal override IEnumerable ExecuteSelect (DataSourceSelectArguments arguments)
  575. {
  576. arguments.RaiseUnsupportedCapabilitiesError (this);
  577. IOrderedDictionary paramValues = MergeParameterValues (SelectParameters, null, null, true);
  578. ObjectDataSourceSelectingEventArgs args = new ObjectDataSourceSelectingEventArgs (paramValues, arguments, false);
  579. OnSelecting (args);
  580. if (args.Cancel)
  581. return new ArrayList ();
  582. if (CanRetrieveTotalRowCount && arguments.RetrieveTotalRowCount)
  583. arguments.TotalRowCount = QueryTotalRowCount (paramValues, arguments);
  584. if (CanPage) {
  585. if (StartRowIndexParameterName.Length == 0)
  586. throw new InvalidOperationException ("Paging is enabled, but the StartRowIndexParameterName property is not set.");
  587. if (MaximumRowsParameterName.Length == 0)
  588. throw new InvalidOperationException ("Paging is enabled, but the MaximumRowsParameterName property is not set.");
  589. paramValues [StartRowIndexParameterName] = arguments.StartRowIndex;
  590. paramValues [MaximumRowsParameterName] = arguments.MaximumRows;
  591. }
  592. if (SortParameterName.Length > 0)
  593. paramValues [SortParameterName] = arguments.SortExpression;
  594. object result = InvokeSelect (SelectMethod, paramValues);
  595. if (result is DataSet) {
  596. DataSet dset = (DataSet) result;
  597. if (dset.Tables.Count == 0)
  598. throw new InvalidOperationException ("The select method returnet a DataSet which doesn't contain any table.");
  599. result = dset.Tables [0];
  600. }
  601. if (result is DataTable) {
  602. DataView dview = new DataView ((DataTable)result);
  603. if (arguments.SortExpression != null && arguments.SortExpression.Length > 0) {
  604. dview.Sort = arguments.SortExpression;
  605. }
  606. if (FilterExpression.Length > 0) {
  607. IOrderedDictionary fparams = FilterParameters.GetValues (context, owner);
  608. ObjectDataSourceFilteringEventArgs fargs = new ObjectDataSourceFilteringEventArgs (fparams);
  609. OnFiltering (fargs);
  610. if (!fargs.Cancel) {
  611. object[] formatValues = new object [fparams.Count];
  612. for (int n=0; n<formatValues.Length; n++) {
  613. formatValues [n] = fparams [n];
  614. if (formatValues [n] == null) return dview;
  615. }
  616. dview.RowFilter = string.Format (FilterExpression, formatValues);
  617. }
  618. }
  619. return dview;
  620. }
  621. if (result is IEnumerable)
  622. return (IEnumerable) result;
  623. else
  624. return new object[] { result };
  625. }
  626. int QueryTotalRowCount (IOrderedDictionary mergedParameters, DataSourceSelectArguments arguments)
  627. {
  628. ObjectDataSourceSelectingEventArgs countArgs = new ObjectDataSourceSelectingEventArgs (mergedParameters, arguments, true);
  629. OnSelecting (countArgs);
  630. if (countArgs.Cancel)
  631. return 0;
  632. object count = InvokeSelect (SelectCountMethod, mergedParameters);
  633. return (int) Convert.ChangeType (count, typeof(int));
  634. }
  635. object InvokeSelect (string methodName, IOrderedDictionary paramValues)
  636. {
  637. MethodInfo method = GetObjectMethod (methodName, paramValues);
  638. ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
  639. OnSelected (rargs);
  640. if (rargs.Exception != null && !rargs.ExceptionHandled)
  641. throw rargs.Exception;
  642. return rargs.ReturnValue;
  643. }
  644. ObjectDataSourceStatusEventArgs InvokeMethod (MethodInfo method, IOrderedDictionary paramValues)
  645. {
  646. object instance = null;
  647. if (!method.IsStatic)
  648. instance = CreateObjectInstance ();
  649. ParameterInfo[] pars = method.GetParameters ();
  650. ArrayList outParamInfos;
  651. object[] methodArgs = GetParameterArray (pars, paramValues, out outParamInfos);
  652. if (methodArgs == null)
  653. throw CreateMethodException (method.Name, paramValues);
  654. object result = null;
  655. Hashtable outParams = null;
  656. try {
  657. result = method.Invoke (instance, methodArgs);
  658. if (outParamInfos != null) {
  659. outParams = new Hashtable ();
  660. foreach (ParameterInfo op in outParamInfos)
  661. outParams [op.Name] = methodArgs [op.Position - 1];
  662. }
  663. return new ObjectDataSourceStatusEventArgs (result, outParams, null);
  664. }
  665. catch (Exception ex) {
  666. return new ObjectDataSourceStatusEventArgs (result, outParams, ex);
  667. }
  668. finally {
  669. if (instance != null)
  670. DisposeObjectInstance (instance);
  671. }
  672. }
  673. MethodInfo GetObjectMethod (string methodName, IOrderedDictionary parameters)
  674. {
  675. MemberInfo[] methods = ObjectType.GetMember (methodName);
  676. if (methods.Length > 1) {
  677. // MSDN: The ObjectDataSource resolves method overloads by method name and number
  678. // of parameters; the names and types of the parameters are not considered.
  679. foreach (MemberInfo mi in methods) {
  680. MethodInfo me = mi as MethodInfo;
  681. if (me != null && me.GetParameters().Length == parameters.Count)
  682. return me;
  683. }
  684. }
  685. else if (methods.Length == 1) {
  686. MethodInfo me = methods[0] as MethodInfo;
  687. if (me != null && me.GetParameters().Length == parameters.Count)
  688. return me;
  689. }
  690. throw CreateMethodException (methodName, parameters);
  691. }
  692. MethodInfo ResolveDataObjectMethod (string methodName, IDictionary values, IDictionary oldValues, out IOrderedDictionary paramValues)
  693. {
  694. MethodInfo method;
  695. if (oldValues != null)
  696. method = ObjectType.GetMethod (methodName, new Type[] { DataObjectType, DataObjectType });
  697. else
  698. method = ObjectType.GetMethod (methodName, new Type[] { DataObjectType });
  699. if (method == null)
  700. throw new InvalidOperationException ("ObjectDataSource " + owner.ID + " could not find a method named '" + methodName + "' with parameters of type '" + DataObjectType + "' in '" + ObjectType + "'.");
  701. paramValues = new OrderedDictionary ();
  702. ParameterInfo[] ps = method.GetParameters ();
  703. if (oldValues != null) {
  704. if (FormatOldParameter (ps[0].Name) == ps[1].Name) {
  705. paramValues [ps[0].Name] = CreateDataObject (values);
  706. paramValues [ps[1].Name] = CreateDataObject (oldValues);
  707. } else if (FormatOldParameter (ps[1].Name) == ps[0].Name) {
  708. paramValues [ps[0].Name] = CreateDataObject (oldValues);
  709. paramValues [ps[1].Name] = CreateDataObject (values);
  710. } else
  711. throw new InvalidOperationException ("Method '" + methodName + "' does not have any parameter that fits the value of OldValuesParameterFormatString.");
  712. } else {
  713. paramValues [ps[0].Name] = CreateDataObject (values);
  714. }
  715. return method;
  716. }
  717. Exception CreateMethodException (string methodName, IOrderedDictionary parameters)
  718. {
  719. string s = "";
  720. foreach (string p in parameters.Keys) {
  721. s += p + ", ";
  722. }
  723. return new InvalidOperationException ("ObjectDataSource " + owner.ID + " could not find a method named '" + methodName + "' with parameters " + s + "in type '" + ObjectType + "'.");
  724. }
  725. object CreateDataObject (IDictionary values)
  726. {
  727. object ob = Activator.CreateInstance (DataObjectType);
  728. foreach (DictionaryEntry de in values) {
  729. PropertyInfo p = DataObjectType.GetProperty ((string)de.Key);
  730. if (p == null) throw new InvalidOperationException ("Property " + de.Key + " not found in type '" +DataObjectType + "'.");
  731. p.SetValue (ob, ConvertParameter (p.PropertyType, de.Value), null);
  732. }
  733. return ob;
  734. }
  735. object CreateObjectInstance ()
  736. {
  737. ObjectDataSourceEventArgs args = new ObjectDataSourceEventArgs (null);
  738. OnObjectCreating (args);
  739. if (args.ObjectInstance != null)
  740. return args.ObjectInstance;
  741. object ob = Activator.CreateInstance (ObjectType);
  742. args.ObjectInstance = ob;
  743. OnObjectCreated (args);
  744. return args.ObjectInstance;
  745. }
  746. void DisposeObjectInstance (object obj)
  747. {
  748. ObjectDataSourceDisposingEventArgs args = new ObjectDataSourceDisposingEventArgs (obj);
  749. OnObjectDisposing (args);
  750. if (!args.Cancel) {
  751. IDisposable disp = obj as IDisposable;
  752. if (disp != null) disp.Dispose ();
  753. }
  754. }
  755. /// <summary>
  756. /// Merge the current data item fields with view parameter default values
  757. /// </summary>
  758. /// <param name="viewParams">default parameters</param>
  759. /// <param name="values">new parameters for update and insert</param>
  760. /// <param name="oldValues">old parameters for update and delete</param>
  761. /// <param name="allwaysAddNewValues">true for insert, as current item is
  762. /// irrelevant for insert</param>
  763. /// <returns>merged values</returns>
  764. IOrderedDictionary MergeParameterValues (ParameterCollection viewParams, IDictionary values, IDictionary oldValues, bool allwaysAddNewValues)
  765. {
  766. OrderedDictionary mergedValues = new OrderedDictionary ();
  767. foreach (Parameter p in viewParams) {
  768. bool oldAdded = false;
  769. if (oldValues != null && oldValues.Contains (p.Name)) {
  770. object val = Convert.ChangeType (oldValues [p.Name], p.Type);
  771. mergedValues [FormatOldParameter (p.Name)] = val;
  772. oldAdded = true;
  773. }
  774. if (values != null && values.Contains (p.Name)) {
  775. object val = Convert.ChangeType (values [p.Name], p.Type);
  776. mergedValues [p.Name] = val;
  777. } else if (!oldAdded || allwaysAddNewValues) {
  778. object val = p.GetValue (context, owner);
  779. mergedValues [p.Name] = val;
  780. }
  781. }
  782. if (values != null) {
  783. foreach (DictionaryEntry de in values)
  784. if (!mergedValues.Contains (de.Key))
  785. mergedValues [de.Key] = de.Value;
  786. }
  787. if (oldValues != null) {
  788. foreach (DictionaryEntry de in oldValues)
  789. if (!mergedValues.Contains (FormatOldParameter ((string)de.Key)))
  790. mergedValues [FormatOldParameter ((string)de.Key)] = de.Value;
  791. }
  792. return mergedValues;
  793. }
  794. object[] GetParameterArray (ParameterInfo[] methodParams, IOrderedDictionary viewParams, out ArrayList outParamInfos)
  795. {
  796. // FIXME: make this case insensitive
  797. outParamInfos = null;
  798. object[] values = new object [methodParams.Length];
  799. foreach (ParameterInfo mp in methodParams) {
  800. // Parameter names must match
  801. if (!viewParams.Contains (mp.Name)) return null;
  802. values [mp.Position] = ConvertParameter (mp.ParameterType, viewParams [mp.Name]);
  803. if (mp.ParameterType.IsByRef) {
  804. if (outParamInfos == null) outParamInfos = new ArrayList ();
  805. outParamInfos.Add (mp);
  806. }
  807. }
  808. return values;
  809. }
  810. object ConvertParameter (Type targetType, object value)
  811. {
  812. return ConvertParameter (Type.GetTypeCode (targetType), value);
  813. }
  814. object ConvertParameter (TypeCode targetType, object value)
  815. {
  816. if (value == null) {
  817. if (targetType != TypeCode.Object && targetType != TypeCode.String)
  818. value = 0;
  819. else if (targetType == TypeCode.Object && ConvertNullToDBNull)
  820. return DBNull.Value;
  821. }
  822. if (targetType == TypeCode.Object)
  823. return value;
  824. else
  825. return Convert.ChangeType (value, targetType);
  826. }
  827. string FormatOldParameter (string name)
  828. {
  829. string f = OldValuesParameterFormatString;
  830. if (f.Length > 0)
  831. return String.Format (f, name);
  832. else
  833. return name;
  834. }
  835. void OnParametersChanged (object sender, EventArgs args)
  836. {
  837. OnDataSourceViewChanged (EventArgs.Empty);
  838. }
  839. protected virtual void LoadViewState (object savedState)
  840. {
  841. object[] state = (savedState == null) ? new object [6] : (object[]) savedState;
  842. viewState.LoadViewState (state[0]);
  843. ((IStateManager)SelectParameters).LoadViewState (state[1]);
  844. ((IStateManager)UpdateParameters).LoadViewState (state[2]);
  845. ((IStateManager)DeleteParameters).LoadViewState (state[3]);
  846. ((IStateManager)InsertParameters).LoadViewState (state[4]);
  847. ((IStateManager)FilterParameters).LoadViewState (state[5]);
  848. }
  849. protected virtual object SaveViewState()
  850. {
  851. object[] state = new object [6];
  852. state [0] = viewState.SaveViewState ();
  853. if (selectParameters != null)
  854. state [1] = ((IStateManager)selectParameters).SaveViewState ();
  855. if (updateParameters != null)
  856. state [2] = ((IStateManager)updateParameters).SaveViewState ();
  857. if (deleteParameters != null)
  858. state [3] = ((IStateManager)deleteParameters).SaveViewState ();
  859. if (insertParameters != null)
  860. state [4] = ((IStateManager)insertParameters).SaveViewState ();
  861. if (filterParameters != null)
  862. state [5] = ((IStateManager)filterParameters).SaveViewState ();
  863. foreach (object ob in state)
  864. if (ob != null) return state;
  865. return null;
  866. }
  867. protected virtual void TrackViewState()
  868. {
  869. viewState.TrackViewState ();
  870. if (selectParameters != null) ((IStateManager)selectParameters).TrackViewState ();
  871. if (updateParameters != null) ((IStateManager)updateParameters).TrackViewState ();
  872. if (deleteParameters != null) ((IStateManager)deleteParameters).TrackViewState ();
  873. if (insertParameters != null) ((IStateManager)insertParameters).TrackViewState ();
  874. if (filterParameters != null) ((IStateManager)filterParameters).TrackViewState ();
  875. }
  876. protected bool IsTrackingViewState
  877. {
  878. get { return viewState.IsTrackingViewState; }
  879. }
  880. bool IStateManager.IsTrackingViewState
  881. {
  882. get { return IsTrackingViewState; }
  883. }
  884. void IStateManager.TrackViewState()
  885. {
  886. TrackViewState ();
  887. }
  888. void IStateManager.LoadViewState (object savedState)
  889. {
  890. LoadViewState (savedState);
  891. }
  892. object IStateManager.SaveViewState()
  893. {
  894. return SaveViewState ();
  895. }
  896. }
  897. }
  898. #endif