2 // System.Web.UI.WebControls.ObjectDataSourceView
5 // Lluis Sanchez Gual (lluis@novell.com)
7 // (C) 2005 Novell, Inc. (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Reflection;
34 using System.Collections;
35 using System.Collections.Specialized;
36 using System.ComponentModel;
40 namespace System.Web.UI.WebControls
43 public class ObjectDataSourceView : DataSourceView, IStateManager
45 ObjectDataSource owner;
50 StateBag viewState = new StateBag ();
51 ParameterCollection selectParameters;
52 ParameterCollection updateParameters;
53 ParameterCollection deleteParameters;
54 ParameterCollection insertParameters;
55 ParameterCollection filterParameters;
57 private static readonly object DeletedEvent = new object();
58 private static readonly object DeletingEvent = new object();
59 private static readonly object FilteringEvent = new object();
60 private static readonly object InsertedEvent = new object();
61 private static readonly object InsertingEvent = new object();
62 private static readonly object ObjectCreatedEvent = new object();
63 private static readonly object ObjectCreatingEvent = new object();
64 private static readonly object ObjectDisposingEvent = new object();
65 // private static readonly object ResolvingMethodEvent = new object();
66 private static readonly object SelectedEvent = new object();
67 private static readonly object SelectingEvent = new object();
68 private static readonly object UpdatedEvent = new object();
69 private static readonly object UpdatingEvent = new object();
71 public ObjectDataSourceView (ObjectDataSource owner, string name, HttpContext context): base (owner, name)
74 this.context = context;
77 public event ObjectDataSourceStatusEventHandler Deleted {
78 add { Events.AddHandler (DeletedEvent, value); }
79 remove { Events.RemoveHandler (DeletedEvent, value); }
82 public event ObjectDataSourceMethodEventHandler Deleting {
83 add { Events.AddHandler (DeletingEvent, value); }
84 remove { Events.RemoveHandler (DeletingEvent, value); }
87 public event ObjectDataSourceFilteringEventHandler Filtering {
88 add { Events.AddHandler (FilteringEvent, value); }
89 remove { Events.RemoveHandler (FilteringEvent, value); }
92 public event ObjectDataSourceStatusEventHandler Inserted {
93 add { Events.AddHandler (InsertedEvent, value); }
94 remove { Events.RemoveHandler (InsertedEvent, value); }
97 public event ObjectDataSourceMethodEventHandler Inserting {
98 add { Events.AddHandler (InsertingEvent, value); }
99 remove { Events.RemoveHandler (InsertingEvent, value); }
102 public event ObjectDataSourceObjectEventHandler ObjectCreated {
103 add { Events.AddHandler (ObjectCreatedEvent, value); }
104 remove { Events.RemoveHandler (ObjectCreatedEvent, value); }
107 public event ObjectDataSourceObjectEventHandler ObjectCreating {
108 add { Events.AddHandler (ObjectCreatingEvent, value); }
109 remove { Events.RemoveHandler (ObjectCreatingEvent, value); }
112 public event ObjectDataSourceDisposingEventHandler ObjectDisposing {
113 add { Events.AddHandler (ObjectDisposingEvent, value); }
114 remove { Events.RemoveHandler (ObjectDisposingEvent, value); }
117 /* public event ObjectDataSourceResolvingMethodEventHandler ResolvingMethod {
118 add { Events.AddHandler (ResolvingMethodEvent, value); }
119 remove { Events.RemoveHandler (ResolvingMethodEvent, value); }
122 public event ObjectDataSourceStatusEventHandler Selected {
123 add { Events.AddHandler (SelectedEvent, value); }
124 remove { Events.RemoveHandler (SelectedEvent, value); }
127 public event ObjectDataSourceSelectingEventHandler Selecting {
128 add { Events.AddHandler (SelectingEvent, value); }
129 remove { Events.RemoveHandler (SelectingEvent, value); }
132 public event ObjectDataSourceStatusEventHandler Updated {
133 add { Events.AddHandler (UpdatedEvent, value); }
134 remove { Events.RemoveHandler (UpdatedEvent, value); }
137 public event ObjectDataSourceMethodEventHandler Updating {
138 add { Events.AddHandler (UpdatingEvent, value); }
139 remove { Events.RemoveHandler (UpdatingEvent, value); }
142 protected virtual void OnDeleted (ObjectDataSourceStatusEventArgs e)
144 if (Events != null) {
145 ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [DeletedEvent];
146 if (eh != null) eh (this, e);
150 protected virtual void OnDeleting (ObjectDataSourceMethodEventArgs e)
152 if (Events != null) {
153 ObjectDataSourceMethodEventHandler eh = (ObjectDataSourceMethodEventHandler) Events [DeletingEvent];
154 if (eh != null) eh (this, e);
158 protected virtual void OnFiltering (ObjectDataSourceFilteringEventArgs e)
160 if (Events != null) {
161 ObjectDataSourceFilteringEventHandler eh = (ObjectDataSourceFilteringEventHandler) Events [FilteringEvent];
162 if (eh != null) eh (this, e);
166 protected virtual void OnInserted (ObjectDataSourceStatusEventArgs e)
168 if (Events != null) {
169 ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [InsertedEvent];
170 if (eh != null) eh (this, e);
174 protected virtual void OnInserting (ObjectDataSourceMethodEventArgs e)
176 if (Events != null) {
177 ObjectDataSourceMethodEventHandler eh = (ObjectDataSourceMethodEventHandler) Events [InsertingEvent];
178 if (eh != null) eh (this, e);
182 protected virtual void OnObjectCreated (ObjectDataSourceEventArgs e)
184 if (Events != null) {
185 ObjectDataSourceObjectEventHandler eh = (ObjectDataSourceObjectEventHandler) Events [ObjectCreatedEvent];
186 if (eh != null) eh (this, e);
190 protected virtual void OnObjectCreating (ObjectDataSourceEventArgs e)
192 if (Events != null) {
193 ObjectDataSourceObjectEventHandler eh = (ObjectDataSourceObjectEventHandler) Events [ObjectCreatingEvent];
194 if (eh != null) eh (this, e);
198 protected virtual void OnObjectDisposing (ObjectDataSourceDisposingEventArgs e)
200 if (Events != null) {
201 ObjectDataSourceDisposingEventHandler eh = (ObjectDataSourceDisposingEventHandler) Events [ObjectDisposingEvent];
202 if (eh != null) eh (this, e);
206 /* protected virtual void OnResolvingMethod (ObjectDataSourceResolvingMethodEventArgs e)
208 if (Events != null) {
209 ObjectDataSourceResolvingMethodEventHandler eh = (ObjectDataSourceResolvingMethodEventHandler) Events [ResolvingMethodEvent];
210 if (eh != null) eh (this, e);
215 protected virtual void OnSelected (ObjectDataSourceStatusEventArgs e)
217 if (Events != null) {
218 ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [SelectedEvent];
219 if (eh != null) eh (this, e);
223 protected virtual void OnSelecting (ObjectDataSourceSelectingEventArgs e)
225 if (Events != null) {
226 ObjectDataSourceSelectingEventHandler eh = (ObjectDataSourceSelectingEventHandler) Events [SelectingEvent];
227 if (eh != null) eh (this, e);
231 protected virtual void OnUpdated (ObjectDataSourceStatusEventArgs e)
233 if (Events != null) {
234 ObjectDataSourceStatusEventHandler eh = (ObjectDataSourceStatusEventHandler) Events [UpdatedEvent];
235 if (eh != null) eh (this, e);
239 protected virtual void OnUpdating (ObjectDataSourceMethodEventArgs e)
241 if (Events != null) {
242 ObjectDataSourceMethodEventHandler eh = (ObjectDataSourceMethodEventHandler) Events [UpdatingEvent];
243 if (eh != null) eh (this, e);
248 get { return viewState; }
251 public override bool CanDelete {
252 get { return DeleteMethod.Length > 0; }
255 public override bool CanInsert {
256 get { return InsertMethod.Length > 0; }
259 public override bool CanPage {
260 get { return EnablePaging; }
263 public override bool CanRetrieveTotalRowCount {
264 get { return SelectCountMethod.Length > 0; }
267 public override bool CanSort {
271 public override bool CanUpdate {
272 get { return UpdateMethod.Length > 0; }
275 public ConflictOptions ConflictDetection {
277 object ret = ViewState ["ConflictDetection"];
278 return ret != null ? (ConflictOptions)ret : ConflictOptions.OverwriteChanges;
281 ViewState ["ConflictDetection"] = value;
285 public bool ConvertNullToDBNull {
287 object ret = ViewState ["ConvertNullToDBNull"];
288 return ret != null ? (bool)ret : false;
291 ViewState ["ConvertNullToDBNull"] = value;
295 public string DataObjectTypeName {
297 object ret = ViewState ["DataObjectTypeName"];
298 return ret != null ? (string)ret : string.Empty;
301 ViewState ["DataObjectTypeName"] = value;
305 public string DeleteMethod {
307 object ret = ViewState ["DeleteMethod"];
308 return ret != null ? (string)ret : string.Empty;
311 ViewState ["DeleteMethod"] = value;
315 public ParameterCollection DeleteParameters {
317 if (deleteParameters == null) {
318 deleteParameters = new ParameterCollection ();
319 deleteParameters.ParametersChanged += new EventHandler (OnParametersChanged);
320 if (IsTrackingViewState)
321 ((IStateManager)deleteParameters).TrackViewState ();
323 return deleteParameters;
327 public bool EnablePaging {
329 object ret = ViewState ["EnablePaging"];
330 return ret != null ? (bool)ret : false;
333 ViewState ["EnablePaging"] = value;
337 public string FilterExpression {
339 object ret = ViewState ["FilterExpression"];
340 return ret != null ? (string)ret : string.Empty;
343 ViewState ["FilterExpression"] = value;
347 public ParameterCollection FilterParameters {
349 if (filterParameters == null) {
350 filterParameters = new ParameterCollection ();
351 filterParameters.ParametersChanged += new EventHandler (OnParametersChanged);
352 if (IsTrackingViewState)
353 ((IStateManager)filterParameters).TrackViewState ();
355 return filterParameters;
359 public string InsertMethod {
361 object ret = ViewState ["InsertMethod"];
362 return ret != null ? (string)ret : string.Empty;
365 ViewState ["InsertMethod"] = value;
369 public ParameterCollection InsertParameters {
371 if (insertParameters == null) {
372 insertParameters = new ParameterCollection ();
373 insertParameters.ParametersChanged += new EventHandler (OnParametersChanged);
374 if (IsTrackingViewState)
375 ((IStateManager)insertParameters).TrackViewState ();
377 return insertParameters;
381 public string MaximumRowsParameterName {
383 object ret = ViewState ["MaximumRowsParameterName"];
384 return ret != null ? (string)ret : "maximumRows";
387 ViewState ["MaximumRowsParameterName"] = value;
391 [DefaultValueAttribute ("{0}")]
392 public string OldValuesParameterFormatString {
394 object ret = ViewState ["OldValuesParameterFormatString"];
395 return ret != null ? (string)ret : "{0}";
398 ViewState ["OldValuesParameterFormatString"] = value;
402 public string SelectCountMethod {
404 object ret = ViewState ["SelectCountMethod"];
405 return ret != null ? (string)ret : string.Empty;
408 ViewState ["SelectCountMethod"] = value;
412 public string SelectMethod {
414 object ret = ViewState ["SelectMethod"];
415 return ret != null ? (string)ret : string.Empty;
418 ViewState ["SelectMethod"] = value;
422 public ParameterCollection SelectParameters {
424 if (selectParameters == null) {
425 selectParameters = new ParameterCollection ();
426 selectParameters.ParametersChanged += new EventHandler (OnParametersChanged);
427 if (IsTrackingViewState)
428 ((IStateManager)selectParameters).TrackViewState ();
430 return selectParameters;
434 public string SortParameterName {
436 object ret = ViewState ["SortParameterName"];
437 return ret != null ? (string)ret : string.Empty;
440 ViewState ["SortParameterName"] = value;
444 public string StartRowIndexParameterName {
446 object ret = ViewState ["StartRowIndexParameterName"];
447 return ret != null ? (string)ret : "startRowIndex";
450 ViewState ["StartRowIndexParameterName"] = value;
454 public string TypeName {
456 object ret = ViewState ["TypeName"];
457 return ret != null ? (string)ret : string.Empty;
460 ViewState ["TypeName"] = value;
465 public string UpdateMethod {
467 object ret = ViewState ["UpdateMethod"];
468 return ret != null ? (string)ret : string.Empty;
471 ViewState ["UpdateMethod"] = value;
475 public ParameterCollection UpdateParameters {
477 if (updateParameters == null) {
478 updateParameters = new ParameterCollection ();
479 updateParameters.ParametersChanged += new EventHandler (OnParametersChanged);
480 if (IsTrackingViewState)
481 ((IStateManager)updateParameters).TrackViewState ();
483 return updateParameters;
489 if (objectType == null) {
490 objectType = Type.GetType (TypeName);
491 if (objectType == null)
492 throw new InvalidOperationException ("Type not found: " + TypeName);
498 Type DataObjectType {
500 if (dataObjectType == null) {
501 dataObjectType = Type.GetType (DataObjectTypeName);
502 if (objectType == null)
503 throw new InvalidOperationException ("Type not found: " + DataObjectTypeName);
505 return dataObjectType;
509 public IEnumerable Select (DataSourceSelectArguments arguments)
511 return ExecuteSelect (arguments);
514 public int Update (IDictionary keys, IDictionary values, IDictionary oldValues)
516 return ExecuteUpdate (keys, values, oldValues);
519 public int Delete (IDictionary keys, IDictionary oldValues)
521 return ExecuteDelete (keys, oldValues);
524 public int Insert (IDictionary values)
526 return ExecuteInsert (values);
529 protected override int ExecuteInsert (IDictionary values)
532 throw new NotSupportedException ("Insert operation not supported.");
534 IOrderedDictionary paramValues;
537 if (DataObjectTypeName.Length == 0) {
538 paramValues = MergeParameterValues (InsertParameters, values, null, true);
539 method = GetObjectMethod (InsertMethod, paramValues);
541 method = ResolveDataObjectMethod (InsertMethod, values, null, out paramValues);
544 ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
549 ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
552 if (rargs.Exception != null && !rargs.ExceptionHandled)
553 throw rargs.Exception;
555 OnDataSourceViewChanged (EventArgs.Empty);
560 protected override int ExecuteDelete (IDictionary keys, IDictionary oldValues)
563 throw new NotSupportedException ("Delete operation not supported.");
565 if (ConflictDetection == ConflictOptions.CompareAllValues && (oldValues == null || oldValues.Count == 0))
566 throw new InvalidOperationException ("ConflictDetection is set to CompareAllValues and oldValues collection is null or empty.");
568 IDictionary oldDataValues;
569 if (ConflictDetection == ConflictOptions.CompareAllValues) {
570 oldDataValues = new Hashtable ();
571 foreach (DictionaryEntry de in keys)
572 oldDataValues [de.Key] = de.Value;
573 foreach (DictionaryEntry de in oldValues)
574 oldDataValues [de.Key] = de.Value;
576 oldDataValues = keys;
578 IOrderedDictionary paramValues;
581 if (DataObjectTypeName.Length == 0) {
582 paramValues = MergeParameterValues (DeleteParameters, null, oldDataValues, false);
583 method = GetObjectMethod (DeleteMethod, paramValues);
585 method = ResolveDataObjectMethod (DeleteMethod, oldDataValues, null, out paramValues);
588 ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
593 ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
597 if (rargs.Exception != null && !rargs.ExceptionHandled)
598 throw rargs.Exception;
600 OnDataSourceViewChanged (EventArgs.Empty);
605 protected override int ExecuteUpdate (IDictionary keys, IDictionary values, IDictionary oldValues)
607 IOrderedDictionary paramValues;
610 if (DataObjectTypeName.Length == 0)
612 IDictionary dataValues;
613 IDictionary oldDataValues;
614 if (ConflictDetection == ConflictOptions.CompareAllValues) {
615 oldDataValues = new Hashtable ();
617 foreach (DictionaryEntry de in keys)
618 oldDataValues [de.Key] = de.Value;
619 foreach (DictionaryEntry de in oldValues)
620 oldDataValues [de.Key] = de.Value;
622 oldDataValues = keys;
625 paramValues = MergeParameterValues (UpdateParameters, dataValues, oldDataValues, false);
626 method = GetObjectMethod (UpdateMethod, paramValues);
630 IDictionary dataValues = new Hashtable ();
631 IDictionary oldDataValues;
633 foreach (DictionaryEntry de in values)
634 dataValues [de.Key] = de.Value;
636 if (ConflictDetection == ConflictOptions.CompareAllValues) {
637 oldDataValues = new Hashtable ();
638 foreach (DictionaryEntry de in keys) {
639 oldDataValues [de.Key] = de.Value;
640 dataValues [de.Key] = de.Value;
642 foreach (DictionaryEntry de in oldValues)
643 oldDataValues [de.Key] = de.Value;
645 oldDataValues = null;
646 foreach (DictionaryEntry de in keys)
647 dataValues [de.Key] = de.Value;
649 method = ResolveDataObjectMethod (UpdateMethod, dataValues, oldDataValues, out paramValues);
652 ObjectDataSourceMethodEventArgs args = new ObjectDataSourceMethodEventArgs (paramValues);
657 ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
660 if (rargs.Exception != null && !rargs.ExceptionHandled)
661 throw rargs.Exception;
663 OnDataSourceViewChanged (EventArgs.Empty);
668 protected internal override IEnumerable ExecuteSelect (DataSourceSelectArguments arguments)
670 arguments.RaiseUnsupportedCapabilitiesError (this);
672 IOrderedDictionary paramValues = MergeParameterValues (SelectParameters, null, null, true);
673 ObjectDataSourceSelectingEventArgs args = new ObjectDataSourceSelectingEventArgs (paramValues, arguments, false);
676 return new ArrayList ();
678 if (CanRetrieveTotalRowCount && arguments.RetrieveTotalRowCount)
679 arguments.TotalRowCount = QueryTotalRowCount (paramValues, arguments);
682 if (StartRowIndexParameterName.Length == 0)
683 throw new InvalidOperationException ("Paging is enabled, but the StartRowIndexParameterName property is not set.");
684 if (MaximumRowsParameterName.Length == 0)
685 throw new InvalidOperationException ("Paging is enabled, but the MaximumRowsParameterName property is not set.");
686 paramValues [StartRowIndexParameterName] = arguments.StartRowIndex;
687 paramValues [MaximumRowsParameterName] = arguments.MaximumRows;
690 if (SortParameterName.Length > 0)
691 paramValues [SortParameterName] = arguments.SortExpression;
693 object result = InvokeSelect (SelectMethod, paramValues);
695 if (result is DataSet) {
696 DataSet dset = (DataSet) result;
697 if (dset.Tables.Count == 0)
698 throw new InvalidOperationException ("The select method returnet a DataSet which doesn't contain any table.");
699 result = dset.Tables [0];
702 if (result is DataTable) {
703 DataView dview = new DataView ((DataTable)result);
704 if (arguments.SortExpression != null && arguments.SortExpression.Length > 0) {
705 dview.Sort = arguments.SortExpression;
707 if (FilterExpression.Length > 0) {
708 IOrderedDictionary fparams = FilterParameters.GetValues (context, owner);
709 ObjectDataSourceFilteringEventArgs fargs = new ObjectDataSourceFilteringEventArgs (fparams);
712 object[] formatValues = new object [fparams.Count];
713 for (int n=0; n<formatValues.Length; n++) {
714 formatValues [n] = fparams [n];
715 if (formatValues [n] == null) return dview;
717 dview.RowFilter = string.Format (FilterExpression, formatValues);
723 if (result is IEnumerable)
724 return (IEnumerable) result;
726 return new object[] { result };
729 int QueryTotalRowCount (IOrderedDictionary mergedParameters, DataSourceSelectArguments arguments)
731 ObjectDataSourceSelectingEventArgs countArgs = new ObjectDataSourceSelectingEventArgs (mergedParameters, arguments, true);
732 OnSelecting (countArgs);
733 if (countArgs.Cancel)
736 object count = InvokeSelect (SelectCountMethod, mergedParameters);
737 return (int) Convert.ChangeType (count, typeof(int));
740 object InvokeSelect (string methodName, IOrderedDictionary paramValues)
742 MethodInfo method = GetObjectMethod (methodName, paramValues);
743 ObjectDataSourceStatusEventArgs rargs = InvokeMethod (method, paramValues);
746 if (rargs.Exception != null && !rargs.ExceptionHandled)
747 throw rargs.Exception;
749 return rargs.ReturnValue;
752 ObjectDataSourceStatusEventArgs InvokeMethod (MethodInfo method, IOrderedDictionary paramValues)
754 object instance = null;
756 if (!method.IsStatic)
757 instance = CreateObjectInstance ();
759 ParameterInfo[] pars = method.GetParameters ();
761 ArrayList outParamInfos;
762 object[] methodArgs = GetParameterArray (pars, paramValues, out outParamInfos);
764 if (methodArgs == null)
765 throw CreateMethodException (method.Name, paramValues);
767 object result = null;
768 Hashtable outParams = null;
771 result = method.Invoke (instance, methodArgs);
772 if (outParamInfos != null) {
773 outParams = new Hashtable ();
774 foreach (ParameterInfo op in outParamInfos)
775 outParams [op.Name] = methodArgs [op.Position - 1];
777 return new ObjectDataSourceStatusEventArgs (result, outParams, null);
779 catch (Exception ex) {
780 return new ObjectDataSourceStatusEventArgs (result, outParams, ex);
783 if (instance != null)
784 DisposeObjectInstance (instance);
788 MethodInfo GetObjectMethod (string methodName, IOrderedDictionary parameters)
790 MemberInfo[] methods = ObjectType.GetMember (methodName);
791 if (methods.Length > 1) {
792 // MSDN: The ObjectDataSource resolves method overloads by method name and number
793 // of parameters; the names and types of the parameters are not considered.
794 foreach (MemberInfo mi in methods) {
795 MethodInfo me = mi as MethodInfo;
796 if (me != null && me.GetParameters().Length == parameters.Count)
800 else if (methods.Length == 1) {
801 MethodInfo me = methods[0] as MethodInfo;
802 if (me != null && me.GetParameters().Length == parameters.Count)
806 throw CreateMethodException (methodName, parameters);
809 MethodInfo ResolveDataObjectMethod (string methodName, IDictionary values, IDictionary oldValues, out IOrderedDictionary paramValues)
812 if (oldValues != null)
813 method = ObjectType.GetMethod (methodName, new Type[] { DataObjectType, DataObjectType });
815 method = ObjectType.GetMethod (methodName, new Type[] { DataObjectType });
818 throw new InvalidOperationException ("ObjectDataSource " + owner.ID + " could not find a method named '" + methodName + "' with parameters of type '" + DataObjectType + "' in '" + ObjectType + "'.");
820 paramValues = new OrderedDictionary ();
821 ParameterInfo[] ps = method.GetParameters ();
823 if (oldValues != null) {
824 if (FormatOldParameter (ps[0].Name) == ps[1].Name) {
825 paramValues [ps[0].Name] = CreateDataObject (values);
826 paramValues [ps[1].Name] = CreateDataObject (oldValues);
827 } else if (FormatOldParameter (ps[1].Name) == ps[0].Name) {
828 paramValues [ps[0].Name] = CreateDataObject (oldValues);
829 paramValues [ps[1].Name] = CreateDataObject (values);
831 throw new InvalidOperationException ("Method '" + methodName + "' does not have any parameter that fits the value of OldValuesParameterFormatString.");
833 paramValues [ps[0].Name] = CreateDataObject (values);
838 Exception CreateMethodException (string methodName, IOrderedDictionary parameters)
841 foreach (string p in parameters.Keys) {
844 return new InvalidOperationException ("ObjectDataSource " + owner.ID + " could not find a method named '" + methodName + "' with parameters " + s + "in type '" + ObjectType + "'.");
847 object CreateDataObject (IDictionary values)
849 object ob = Activator.CreateInstance (DataObjectType);
850 foreach (DictionaryEntry de in values) {
851 PropertyInfo p = DataObjectType.GetProperty ((string)de.Key);
852 if (p == null) throw new InvalidOperationException ("Property " + de.Key + " not found in type '" +DataObjectType + "'.");
853 p.SetValue (ob, ConvertParameter (p.PropertyType, de.Value), null);
858 object CreateObjectInstance ()
860 ObjectDataSourceEventArgs args = new ObjectDataSourceEventArgs (null);
861 OnObjectCreating (args);
863 if (args.ObjectInstance != null)
864 return args.ObjectInstance;
866 object ob = Activator.CreateInstance (ObjectType);
868 args.ObjectInstance = ob;
869 OnObjectCreated (args);
871 return args.ObjectInstance;
874 void DisposeObjectInstance (object obj)
876 ObjectDataSourceDisposingEventArgs args = new ObjectDataSourceDisposingEventArgs (obj);
877 OnObjectDisposing (args);
880 IDisposable disp = obj as IDisposable;
881 if (disp != null) disp.Dispose ();
886 /// Merge the current data item fields with view parameter default values
\r
888 /// <param name="viewParams">default parameters</param>
\r
889 /// <param name="values">new parameters for update and insert</param>
\r
890 /// <param name="oldValues">old parameters for update and delete</param>
\r
891 /// <param name="allwaysAddNewValues">true for insert, as current item is
\r
892 /// irrelevant for insert</param>
\r
893 /// <returns>merged values</returns>
894 IOrderedDictionary MergeParameterValues (ParameterCollection viewParams, IDictionary values, IDictionary oldValues, bool allwaysAddNewValues)
896 OrderedDictionary mergedValues = new OrderedDictionary ();
897 foreach (Parameter p in viewParams) {
898 bool oldAdded = false;
899 if (oldValues != null && oldValues.Contains (p.Name)) {
900 object val = Convert.ChangeType (oldValues [p.Name], p.Type);
901 mergedValues [FormatOldParameter (p.Name)] = val;
905 if (values != null && values.Contains (p.Name)) {
906 object val = Convert.ChangeType (values [p.Name], p.Type);
907 mergedValues [p.Name] = val;
908 } else if (!oldAdded || allwaysAddNewValues) {
909 object val = p.GetValue (context, owner);
910 mergedValues [p.Name] = val;
914 if (values != null) {
915 foreach (DictionaryEntry de in values)
916 if (!mergedValues.Contains (de.Key))
917 mergedValues [de.Key] = de.Value;
920 if (oldValues != null) {
921 foreach (DictionaryEntry de in oldValues)
922 if (!mergedValues.Contains (FormatOldParameter ((string)de.Key)))
923 mergedValues [FormatOldParameter ((string)de.Key)] = de.Value;
929 object[] GetParameterArray (ParameterInfo[] methodParams, IOrderedDictionary viewParams, out ArrayList outParamInfos)
931 // FIXME: make this case insensitive
933 outParamInfos = null;
934 object[] values = new object [methodParams.Length];
935 foreach (ParameterInfo mp in methodParams) {
937 // Parameter names must match
938 if (!viewParams.Contains (mp.Name)) return null;
940 values [mp.Position] = ConvertParameter (mp.ParameterType, viewParams [mp.Name]);
941 if (mp.ParameterType.IsByRef) {
942 if (outParamInfos == null) outParamInfos = new ArrayList ();
943 outParamInfos.Add (mp);
949 object ConvertParameter (Type targetType, object value)
951 return ConvertParameter (Type.GetTypeCode (targetType), value);
954 object ConvertParameter (TypeCode targetType, object value)
957 if (targetType != TypeCode.Object && targetType != TypeCode.String)
959 else if (targetType == TypeCode.Object && ConvertNullToDBNull)
962 if (targetType == TypeCode.Object)
965 return Convert.ChangeType (value, targetType);
968 string FormatOldParameter (string name)
970 string f = OldValuesParameterFormatString;
972 return String.Format (f, name);
977 void OnParametersChanged (object sender, EventArgs args)
979 OnDataSourceViewChanged (EventArgs.Empty);
982 protected virtual void LoadViewState (object savedState)
984 object[] state = (savedState == null) ? new object [6] : (object[]) savedState;
985 viewState.LoadViewState (state[0]);
986 ((IStateManager)SelectParameters).LoadViewState (state[1]);
987 ((IStateManager)UpdateParameters).LoadViewState (state[2]);
988 ((IStateManager)DeleteParameters).LoadViewState (state[3]);
989 ((IStateManager)InsertParameters).LoadViewState (state[4]);
990 ((IStateManager)FilterParameters).LoadViewState (state[5]);
993 protected virtual object SaveViewState()
995 object[] state = new object [6];
996 state [0] = viewState.SaveViewState ();
998 if (selectParameters != null)
999 state [1] = ((IStateManager)selectParameters).SaveViewState ();
1000 if (updateParameters != null)
1001 state [2] = ((IStateManager)updateParameters).SaveViewState ();
1002 if (deleteParameters != null)
1003 state [3] = ((IStateManager)deleteParameters).SaveViewState ();
1004 if (insertParameters != null)
1005 state [4] = ((IStateManager)insertParameters).SaveViewState ();
1006 if (filterParameters != null)
1007 state [5] = ((IStateManager)filterParameters).SaveViewState ();
1009 foreach (object ob in state)
1010 if (ob != null) return state;
1015 protected virtual void TrackViewState()
1017 viewState.TrackViewState ();
1018 if (selectParameters != null) ((IStateManager)selectParameters).TrackViewState ();
1019 if (updateParameters != null) ((IStateManager)updateParameters).TrackViewState ();
1020 if (deleteParameters != null) ((IStateManager)deleteParameters).TrackViewState ();
1021 if (insertParameters != null) ((IStateManager)insertParameters).TrackViewState ();
1022 if (filterParameters != null) ((IStateManager)filterParameters).TrackViewState ();
1025 protected bool IsTrackingViewState
1027 get { return viewState.IsTrackingViewState; }
1031 bool IStateManager.IsTrackingViewState
1033 get { return IsTrackingViewState; }
1036 void IStateManager.TrackViewState()
1041 void IStateManager.LoadViewState (object savedState)
1043 LoadViewState (savedState);
1046 object IStateManager.SaveViewState()
1048 return SaveViewState ();