2 // DynamicDataManager.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
6 // Marek Habersack <mhabersack@novell.com>
8 // Copyright (C) 2008-2009 Novell Inc. http://novell.com
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections;
33 using System.Collections.Generic;
34 using System.Collections.Specialized;
35 using System.ComponentModel;
37 using System.Globalization;
38 using System.Security.Permissions;
39 using System.Security.Principal;
40 using System.Web.Caching;
42 using System.Web.UI.WebControls;
43 using System.Web.DynamicData.ModelProviders;
45 namespace System.Web.DynamicData
47 [ToolboxBitmap (typeof(DynamicDataManager), "DynamicDataManager.ico")]
48 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
49 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
51 [ParseChildren (true)]
52 [PersistChildren (false)]
53 public class DynamicDataManager : Control
55 private class AutoFieldGenerator : IAutoFieldGenerator
59 public AutoFieldGenerator (MetaTable table)
64 public ICollection GenerateFields (Control ctl)
66 var ret = new List <DynamicField> ();
67 foreach (MetaColumn column in table.Columns) {
71 var field = new DynamicField ();
72 field.DataField = column.Name;
80 Dictionary <IDynamicDataSource, bool> knownDataSources;
82 public DynamicDataManager ()
86 public bool AutoLoadForeignKeys {
92 public override bool Visible {
95 // NOTE: it is supposed to throw the exception
96 set { throw new NotImplementedException (); }
99 protected override void OnLoad (EventArgs e)
103 // http://forums.asp.net/p/1257004/2339034.aspx
104 // http://forums.asp.net/t/1297860.aspx
105 // http://forums.asp.net/p/1396453/3005197.aspx#3005197
106 if (knownDataSources != null) {
107 foreach (var de in knownDataSources) {
108 IDynamicDataSource dds = de.Key;
112 dds.ExpandDynamicWhereParameters ();
117 public void RegisterControl (Control control)
119 RegisterControl (control, false);
122 public void RegisterControl (Control control, bool setSelectionFromUrl)
124 // .NET doesn't check for null here, but since I don't like such code, we
125 // will do the check and throw the same exception as .NET
127 throw new NullReferenceException ();
129 if (!ControlIsValid (control))
130 throw new Exception ("Controls of type " + control.GetType () + " are not supported.");
132 // http://forums.asp.net/p/1257004/2339034.aspx
133 // http://forums.asp.net/p/1383908/2936065.aspx
134 DataBoundControl dbc = control as DataBoundControl;
136 IDynamicDataSource dds = dbc.DataSourceObject as IDynamicDataSource;
140 RegisterDataSource (dds);
141 MetaTable table = dds.GetTable ();
145 if (String.IsNullOrEmpty (dds.Where))
146 dds.AutoGenerateWhereClause = true;
148 dds.AutoGenerateWhereClause = false;
150 Type contextType = dds.ContextType;
151 if (contextType == null)
152 dds.ContextType = table.DataContextType;
154 string entityName = dds.EntitySetName;
155 if (String.IsNullOrEmpty (entityName))
156 dds.EntitySetName = table.DataContextPropertyName;
158 if (AutoLoadForeignKeys) {
159 var ldds = dds as LinqDataSource;
161 ldds.LoadWithForeignKeys (table.EntityType);
164 var gv = control as GridView;
166 gv.ColumnsGenerator = new AutoFieldGenerator (table);
170 var dv = control as DetailsView;
172 dv.RowsGenerator = new AutoFieldGenerator (table);
178 void RegisterDataSource (IDynamicDataSource dds)
180 if (knownDataSources == null) {
181 knownDataSources = new Dictionary <IDynamicDataSource, bool> ();
182 knownDataSources.Add (dds, true);
186 if (knownDataSources.ContainsKey (dds))
189 knownDataSources.Add (dds, true);
192 bool ControlIsValid (Control control)
194 if (control is Repeater) {
195 if (control.NamingContainer == null)
196 throw new HttpException ("The Repeater control '" + control.ID + "' does not have a naming container.");
200 DataBoundControl dbc = control as DataBoundControl;