ObjectDataSourceView.cs 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100
  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. private static string privateBinPath;
  428. private static string PrivateBinPath
  429. {
  430. get {
  431. if (privateBinPath != null)
  432. return privateBinPath;
  433. AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
  434. privateBinPath = Path.Combine(setup.ApplicationBase, setup.PrivateBinPath);
  435. return privateBinPath;
  436. }
  437. }
  438. private Type LoadType(string typeName)
  439. {
  440. Type type = null;
  441. Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
  442. foreach (Assembly ass in assemblies) {
  443. type = ass.GetType (typeName);
  444. if (type == null)
  445. continue;
  446. return type;
  447. }
  448. if (!Directory.Exists (PrivateBinPath))
  449. return null;
  450. string[] binDlls = Directory.GetFiles(PrivateBinPath, "*.dll");
  451. foreach (string s in binDlls) {
  452. Assembly binA = Assembly.LoadFrom (s);
  453. type = binA.GetType (typeName);
  454. if (type == null)
  455. continue;
  456. return type;
  457. }
  458. return null;
  459. }
  460. Type ObjectType {
  461. get {
  462. if (objectType == null) {
  463. objectType = LoadType (TypeName);
  464. if (objectType == null)
  465. throw new InvalidOperationException ("Type not found: " + TypeName);
  466. }
  467. return objectType;
  468. }
  469. }
  470. Type DataObjectType {
  471. get {
  472. if (dataObjectType == null) {
  473. dataObjectType = LoadType (DataObjectTypeName);
  474. if (objectType == null)
  475. throw new InvalidOperationException ("Type not found: " + DataObjectTypeName);
  476. }
  477. return dataObjectType;
  478. }
  479. }
  480. public IEnumerable Select (DataSourceSelectArguments arguments)
  481. {
  482. return ExecuteSelect (arguments);
  483. }
  484. public int Update (IDictionary keys, IDictionary values, IDictionary oldValues)
  485. {
  486. return ExecuteUpdate (keys, values, oldValues);
  487. }
  488. public int Delete (IDictionary keys, IDictionary oldValues)
  489. {
  490. return ExecuteDelete (keys, oldValues);
  491. }
  492. public int Insert (IDictionary values)
  493. {
  494. return ExecuteInsert (values);
  495. }
  496. protected override int ExecuteInsert (IDictionary values)
  497. {
  498. if (!CanInsert)
  499. throw new NotSupportedException ("Insert operation not supported.");
  500. IOrderedDictionary paramValues;
  501. MethodInfo method;
  502. if (DataObjectTypeName.Length == 0) {
  503. paramValues = MergeParameterValues (InsertParameters, values, null, true);
  504. method = GetObjectMethod (InsertMethod, paramValues);
  505. } else {
  506. method = ResolveDataObjectMethod (InsertMethod, values, null, out paramValues);
  507. }
  508. ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
  509. OnInserting (args);
  510. if (args.Cancel)
  511. return -1;
  512. ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
  513. OnInserted (rargs);
  514. if (rargs.Exception != null && !rargs.ExceptionHandled)
  515. throw rargs.Exception;
  516. OnDataSourceViewChanged (EventArgs.Empty);
  517. return -1;
  518. }
  519. protected override int ExecuteDelete (IDictionary keys, IDictionary oldValues)
  520. {
  521. if (!CanDelete)
  522. throw new NotSupportedException ("Delete operation not supported.");
  523. if (ConflictDetection == ConflictOptions.CompareAllValues && (oldValues == null || oldValues.Count == 0))
  524. throw new InvalidOperationException ("ConflictDetection is set to CompareAllValues and oldValues collection is null or empty.");
  525. IDictionary oldDataValues;
  526. if (ConflictDetection == ConflictOptions.CompareAllValues) {
  527. oldDataValues = new Hashtable ();
  528. foreach (DictionaryEntry de in keys)
  529. oldDataValues [de.Key] = de.Value;
  530. foreach (DictionaryEntry de in oldValues)
  531. oldDataValues [de.Key] = de.Value;
  532. } else
  533. oldDataValues = keys;
  534. IOrderedDictionary paramValues;
  535. MethodInfo method;
  536. if (DataObjectTypeName.Length == 0) {
  537. paramValues = MergeParameterValues (DeleteParameters, null, oldDataValues, false);
  538. method = GetObjectMethod (DeleteMethod, paramValues);
  539. } else {
  540. method = ResolveDataObjectMethod (DeleteMethod, oldDataValues, null, out paramValues);
  541. }
  542. ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
  543. OnDeleting (args);
  544. if (args.Cancel)
  545. return -1;
  546. ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
  547. OnDeleted (rargs);
  548. if (rargs.Exception != null && !rargs.ExceptionHandled)
  549. throw rargs.Exception;
  550. OnDataSourceViewChanged (EventArgs.Empty);
  551. return -1;
  552. }
  553. protected override int ExecuteUpdate (IDictionary keys, IDictionary values, IDictionary oldValues)
  554. {
  555. IOrderedDictionary paramValues;
  556. MethodInfo method;
  557. if (DataObjectTypeName.Length == 0)
  558. {
  559. IDictionary dataValues;
  560. IDictionary oldDataValues;
  561. if (ConflictDetection == ConflictOptions.CompareAllValues) {
  562. oldDataValues = new Hashtable ();
  563. dataValues = values;
  564. foreach (DictionaryEntry de in keys)
  565. oldDataValues [de.Key] = de.Value;
  566. foreach (DictionaryEntry de in oldValues)
  567. oldDataValues [de.Key] = de.Value;
  568. } else {
  569. oldDataValues = keys;
  570. dataValues = values;
  571. }
  572. paramValues = MergeParameterValues (UpdateParameters, dataValues, oldDataValues, false);
  573. method = GetObjectMethod (UpdateMethod, paramValues);
  574. }
  575. else
  576. {
  577. IDictionary dataValues = new Hashtable ();
  578. IDictionary oldDataValues;
  579. foreach (DictionaryEntry de in values)
  580. dataValues [de.Key] = de.Value;
  581. if (ConflictDetection == ConflictOptions.CompareAllValues) {
  582. oldDataValues = new Hashtable ();
  583. foreach (DictionaryEntry de in keys) {
  584. oldDataValues [de.Key] = de.Value;
  585. dataValues [de.Key] = de.Value;
  586. }
  587. foreach (DictionaryEntry de in oldValues)
  588. oldDataValues [de.Key] = de.Value;
  589. } else {
  590. oldDataValues = null;
  591. foreach (DictionaryEntry de in keys)
  592. dataValues [de.Key] = de.Value;
  593. }
  594. method = ResolveDataObjectMethod (UpdateMethod, dataValues, oldDataValues, out paramValues);
  595. }
  596. ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
  597. OnUpdating (args);
  598. if (args.Cancel)
  599. return -1;
  600. ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
  601. OnUpdated (rargs);
  602. if (rargs.Exception != null && !rargs.ExceptionHandled)
  603. throw rargs.Exception;
  604. OnDataSourceViewChanged (EventArgs.Empty);
  605. return -1;
  606. }
  607. protected internal override IEnumerable ExecuteSelect (DataSourceSelectArguments arguments)
  608. {
  609. arguments.RaiseUnsupportedCapabilitiesError (this);
  610. IOrderedDictionary paramValues = MergeParameterValues (SelectParameters, null, null, true);
  611. ObjectDataSourceSelectingEventArgs args = new ObjectDataSourceSelectingEventArgs (paramValues, arguments, false);
  612. OnSelecting (args);
  613. if (args.Cancel)
  614. return new ArrayList ();
  615. if (CanRetrieveTotalRowCount && arguments.RetrieveTotalRowCount)
  616. arguments.TotalRowCount = QueryTotalRowCount (paramValues, arguments);
  617. if (CanPage) {
  618. if (StartRowIndexParameterName.Length == 0)
  619. throw new InvalidOperationException ("Paging is enabled, but the StartRowIndexParameterName property is not set.");
  620. if (MaximumRowsParameterName.Length == 0)
  621. throw new InvalidOperationException ("Paging is enabled, but the MaximumRowsParameterName property is not set.");
  622. paramValues [StartRowIndexParameterName] = arguments.StartRowIndex;
  623. paramValues [MaximumRowsParameterName] = arguments.MaximumRows;
  624. }
  625. if (SortParameterName.Length > 0)
  626. paramValues [SortParameterName] = arguments.SortExpression;
  627. object result = InvokeSelect (SelectMethod, paramValues);
  628. if (result is DataSet) {
  629. DataSet dset = (DataSet) result;
  630. if (dset.Tables.Count == 0)
  631. throw new InvalidOperationException ("The select method returnet a DataSet which doesn't contain any table.");
  632. result = dset.Tables [0];
  633. }
  634. if (result is DataTable) {
  635. DataView dview = new DataView ((DataTable)result);
  636. if (arguments.SortExpression != null && arguments.SortExpression.Length > 0) {
  637. dview.Sort = arguments.SortExpression;
  638. }
  639. if (FilterExpression.Length > 0) {
  640. IOrderedDictionary fparams = FilterParameters.GetValues (context, owner);
  641. ObjectDataSourceFilteringEventArgs fargs = new ObjectDataSourceFilteringEventArgs (fparams);
  642. OnFiltering (fargs);
  643. if (!fargs.Cancel) {
  644. object[] formatValues = new object [fparams.Count];
  645. for (int n=0; n<formatValues.Length; n++) {
  646. formatValues [n] = fparams [n];
  647. if (formatValues [n] == null) return dview;
  648. }
  649. dview.RowFilter = string.Format (FilterExpression, formatValues);
  650. }
  651. }
  652. return dview;
  653. }
  654. if (result is IEnumerable)
  655. return (IEnumerable) result;
  656. else
  657. return new object[] { result };
  658. }
  659. int QueryTotalRowCount (IOrderedDictionary mergedParameters, DataSourceSelectArguments arguments)
  660. {
  661. ObjectDataSourceSelectingEventArgs countArgs = new ObjectDataSourceSelectingEventArgs (mergedParameters, arguments, true);
  662. OnSelecting (countArgs);
  663. if (countArgs.Cancel)
  664. return 0;
  665. object count = InvokeSelect (SelectCountMethod, mergedParameters);
  666. return (int) Convert.ChangeType (count, typeof(int));
  667. }
  668. object InvokeSelect (string methodName, IOrderedDictionary paramValues)
  669. {
  670. MethodInfo method = GetObjectMethod (methodName, paramValues);
  671. ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
  672. OnSelected (rargs);
  673. if (rargs.Exception != null && !rargs.ExceptionHandled)
  674. throw rargs.Exception;
  675. return rargs.ReturnValue;
  676. }
  677. ObjectDataSourceStatusEventArgs InvokeMethod (MethodInfo method, IOrderedDictionary paramValues)
  678. {
  679. object instance = null;
  680. if (!method.IsStatic)
  681. instance = CreateObjectInstance ();
  682. ParameterInfo[] pars = method.GetParameters ();
  683. ArrayList outParamInfos;
  684. object[] methodArgs = GetParameterArray (pars, paramValues, out outParamInfos);
  685. if (methodArgs == null)
  686. throw CreateMethodException (method.Name, paramValues);
  687. object result = null;
  688. Hashtable outParams = null;
  689. try {
  690. result = method.Invoke (instance, methodArgs);
  691. if (outParamInfos != null) {
  692. outParams = new Hashtable ();
  693. foreach (ParameterInfo op in outParamInfos)
  694. outParams [op.Name] = methodArgs [op.Position - 1];
  695. }
  696. return new ObjectDataSourceStatusEventArgs (result, outParams, null);
  697. }
  698. catch (Exception ex) {
  699. return new ObjectDataSourceStatusEventArgs (result, outParams, ex);
  700. }
  701. finally {
  702. if (instance != null)
  703. DisposeObjectInstance (instance);
  704. }
  705. }
  706. MethodInfo GetObjectMethod (string methodName, IOrderedDictionary parameters)
  707. {
  708. MemberInfo[] methods = ObjectType.GetMember (methodName, BindingFlags.Instance |
  709. BindingFlags.Static |
  710. BindingFlags.Public |
  711. BindingFlags.FlattenHierarchy);
  712. if (methods.Length > 1) {
  713. // MSDN: The ObjectDataSource resolves method overloads by method name and number
  714. // of parameters; the names and types of the parameters are not considered.
  715. foreach (MemberInfo mi in methods) {
  716. MethodInfo me = mi as MethodInfo;
  717. if (me != null && me.GetParameters().Length == parameters.Count)
  718. return me;
  719. }
  720. }
  721. else if (methods.Length == 1) {
  722. MethodInfo me = methods[0] as MethodInfo;
  723. if (me != null && me.GetParameters().Length == parameters.Count)
  724. return me;
  725. }
  726. throw CreateMethodException (methodName, parameters);
  727. }
  728. MethodInfo ResolveDataObjectMethod (string methodName, IDictionary values, IDictionary oldValues, out IOrderedDictionary paramValues)
  729. {
  730. MethodInfo method;
  731. if (oldValues != null)
  732. method = ObjectType.GetMethod (methodName, new Type[] { DataObjectType, DataObjectType });
  733. else
  734. method = ObjectType.GetMethod (methodName, new Type[] { DataObjectType });
  735. if (method == null)
  736. throw new InvalidOperationException ("ObjectDataSource " + owner.ID + " could not find a method named '" + methodName + "' with parameters of type '" + DataObjectType + "' in '" + ObjectType + "'.");
  737. paramValues = new OrderedDictionary ();
  738. ParameterInfo[] ps = method.GetParameters ();
  739. if (oldValues != null) {
  740. if (FormatOldParameter (ps[0].Name) == ps[1].Name) {
  741. paramValues [ps[0].Name] = CreateDataObject (values);
  742. paramValues [ps[1].Name] = CreateDataObject (oldValues);
  743. } else if (FormatOldParameter (ps[1].Name) == ps[0].Name) {
  744. paramValues [ps[0].Name] = CreateDataObject (oldValues);
  745. paramValues [ps[1].Name] = CreateDataObject (values);
  746. } else
  747. throw new InvalidOperationException ("Method '" + methodName + "' does not have any parameter that fits the value of OldValuesParameterFormatString.");
  748. } else {
  749. paramValues [ps[0].Name] = CreateDataObject (values);
  750. }
  751. return method;
  752. }
  753. Exception CreateMethodException (string methodName, IOrderedDictionary parameters)
  754. {
  755. string s = "";
  756. foreach (string p in parameters.Keys) {
  757. s += p + ", ";
  758. }
  759. return new InvalidOperationException ("ObjectDataSource " + owner.ID + " could not find a method named '" + methodName + "' with parameters " + s + "in type '" + ObjectType + "'.");
  760. }
  761. object CreateDataObject (IDictionary values)
  762. {
  763. object ob = Activator.CreateInstance (DataObjectType);
  764. foreach (DictionaryEntry de in values) {
  765. PropertyInfo p = DataObjectType.GetProperty ((string)de.Key);
  766. if (p == null) throw new InvalidOperationException ("Property " + de.Key + " not found in type '" +DataObjectType + "'.");
  767. p.SetValue (ob, ConvertParameter (p.PropertyType, de.Value), null);
  768. }
  769. return ob;
  770. }
  771. object CreateObjectInstance ()
  772. {
  773. ObjectDataSourceEventArgs args = new ObjectDataSourceEventArgs (null);
  774. OnObjectCreating (args);
  775. if (args.ObjectInstance != null)
  776. return args.ObjectInstance;
  777. object ob = Activator.CreateInstance (ObjectType);
  778. args.ObjectInstance = ob;
  779. OnObjectCreated (args);
  780. return args.ObjectInstance;
  781. }
  782. void DisposeObjectInstance (object obj)
  783. {
  784. ObjectDataSourceDisposingEventArgs args = new ObjectDataSourceDisposingEventArgs (obj);
  785. OnObjectDisposing (args);
  786. if (!args.Cancel) {
  787. IDisposable disp = obj as IDisposable;
  788. if (disp != null) disp.Dispose ();
  789. }
  790. }
  791. /// <summary>
  792. /// Merge the current data item fields with view parameter default values
  793. /// </summary>
  794. /// <param name="viewParams">default parameters</param>
  795. /// <param name="values">new parameters for update and insert</param>
  796. /// <param name="oldValues">old parameters for update and delete</param>
  797. /// <param name="allwaysAddNewValues">true for insert, as current item is
  798. /// irrelevant for insert</param>
  799. /// <returns>merged values</returns>
  800. IOrderedDictionary MergeParameterValues (ParameterCollection viewParams, IDictionary values, IDictionary oldValues, bool allwaysAddNewValues)
  801. {
  802. OrderedDictionary mergedValues = new OrderedDictionary ();
  803. foreach (Parameter p in viewParams) {
  804. bool oldAdded = false;
  805. if (oldValues != null && oldValues.Contains (p.Name)) {
  806. object val = Convert.ChangeType (oldValues [p.Name], p.Type);
  807. mergedValues [FormatOldParameter (p.Name)] = val;
  808. oldAdded = true;
  809. }
  810. if (values != null && values.Contains (p.Name)) {
  811. object val = Convert.ChangeType (values [p.Name], p.Type);
  812. mergedValues [p.Name] = val;
  813. } else if (!oldAdded || allwaysAddNewValues) {
  814. object val = p.GetValue (context, owner);
  815. mergedValues [p.Name] = val;
  816. }
  817. }
  818. if (values != null) {
  819. foreach (DictionaryEntry de in values)
  820. if (!mergedValues.Contains (de.Key))
  821. mergedValues [de.Key] = de.Value;
  822. }
  823. if (oldValues != null) {
  824. foreach (DictionaryEntry de in oldValues)
  825. if (!mergedValues.Contains (FormatOldParameter ((string)de.Key)))
  826. mergedValues [FormatOldParameter ((string)de.Key)] = de.Value;
  827. }
  828. return mergedValues;
  829. }
  830. object[] GetParameterArray (ParameterInfo[] methodParams, IOrderedDictionary viewParams, out ArrayList outParamInfos)
  831. {
  832. // FIXME: make this case insensitive
  833. outParamInfos = null;
  834. object[] values = new object [methodParams.Length];
  835. foreach (ParameterInfo mp in methodParams) {
  836. // Parameter names must match
  837. if (!viewParams.Contains (mp.Name)) return null;
  838. values [mp.Position] = ConvertParameter (mp.ParameterType, viewParams [mp.Name]);
  839. if (mp.ParameterType.IsByRef) {
  840. if (outParamInfos == null) outParamInfos = new ArrayList ();
  841. outParamInfos.Add (mp);
  842. }
  843. }
  844. return values;
  845. }
  846. object ConvertParameter (Type targetType, object value)
  847. {
  848. return ConvertParameter (Type.GetTypeCode (targetType), value);
  849. }
  850. object ConvertParameter (TypeCode targetType, object value)
  851. {
  852. if (value == null) {
  853. if (targetType != TypeCode.Object && targetType != TypeCode.String)
  854. value = 0;
  855. else if (targetType == TypeCode.Object && ConvertNullToDBNull)
  856. return DBNull.Value;
  857. }
  858. if (targetType == TypeCode.Object)
  859. return value;
  860. else
  861. return Convert.ChangeType (value, targetType);
  862. }
  863. string FormatOldParameter (string name)
  864. {
  865. string f = OldValuesParameterFormatString;
  866. if (f.Length > 0)
  867. return String.Format (f, name);
  868. else
  869. return name;
  870. }
  871. void OnParametersChanged (object sender, EventArgs args)
  872. {
  873. OnDataSourceViewChanged (EventArgs.Empty);
  874. }
  875. protected virtual void LoadViewState (object savedState)
  876. {
  877. object[] state = (savedState == null) ? new object [6] : (object[]) savedState;
  878. viewState.LoadViewState (state[0]);
  879. ((IStateManager)SelectParameters).LoadViewState (state[1]);
  880. ((IStateManager)UpdateParameters).LoadViewState (state[2]);
  881. ((IStateManager)DeleteParameters).LoadViewState (state[3]);
  882. ((IStateManager)InsertParameters).LoadViewState (state[4]);
  883. ((IStateManager)FilterParameters).LoadViewState (state[5]);
  884. }
  885. protected virtual object SaveViewState()
  886. {
  887. object[] state = new object [6];
  888. state [0] = viewState.SaveViewState ();
  889. if (selectParameters != null)
  890. state [1] = ((IStateManager)selectParameters).SaveViewState ();
  891. if (updateParameters != null)
  892. state [2] = ((IStateManager)updateParameters).SaveViewState ();
  893. if (deleteParameters != null)
  894. state [3] = ((IStateManager)deleteParameters).SaveViewState ();
  895. if (insertParameters != null)
  896. state [4] = ((IStateManager)insertParameters).SaveViewState ();
  897. if (filterParameters != null)
  898. state [5] = ((IStateManager)filterParameters).SaveViewState ();
  899. foreach (object ob in state)
  900. if (ob != null) return state;
  901. return null;
  902. }
  903. protected virtual void TrackViewState()
  904. {
  905. viewState.TrackViewState ();
  906. if (selectParameters != null) ((IStateManager)selectParameters).TrackViewState ();
  907. if (updateParameters != null) ((IStateManager)updateParameters).TrackViewState ();
  908. if (deleteParameters != null) ((IStateManager)deleteParameters).TrackViewState ();
  909. if (insertParameters != null) ((IStateManager)insertParameters).TrackViewState ();
  910. if (filterParameters != null) ((IStateManager)filterParameters).TrackViewState ();
  911. }
  912. protected bool IsTrackingViewState
  913. {
  914. get { return viewState.IsTrackingViewState; }
  915. }
  916. bool IStateManager.IsTrackingViewState
  917. {
  918. get { return IsTrackingViewState; }
  919. }
  920. void IStateManager.TrackViewState()
  921. {
  922. TrackViewState ();
  923. }
  924. void IStateManager.LoadViewState (object savedState)
  925. {
  926. LoadViewState (savedState);
  927. }
  928. object IStateManager.SaveViewState()
  929. {
  930. return SaveViewState ();
  931. }
  932. }
  933. }
  934. #endif