1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
namespace System.Web.DynamicData.Util {
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Web.Resources;
using System.Web.UI;
using System.ComponentModel;
using IDataBoundControlInterface = System.Web.UI.WebControls.IDataBoundControl;
internal static class MetaTableHelper {
private static object s_mappingKey = new object();
internal static Dictionary<object, MappingInfo> GetMapping(HttpContextBase httpContext) {
Dictionary<object, MappingInfo> mapping = httpContext.Items[s_mappingKey] as Dictionary<object, MappingInfo>;
if (mapping == null) {
mapping = new Dictionary<object, MappingInfo>();
httpContext.Items[s_mappingKey] = mapping;
}
return mapping;
}
/// <summary>
/// Gets a table from the mapping. Does not throw.
/// </summary>
internal static MetaTable GetTableFromMapping(HttpContextBase httpContext, object control) {
IDictionary<object, MappingInfo> mapping = GetMapping(httpContext);
// don't throw if no mapping found
MappingInfo mappingInfo;
if (mapping.TryGetValue(control, out mappingInfo)) {
return mappingInfo.Table;
}
return null;
}
private static MappingInfo GetMappingInfo(object control, HttpContextBase httpContext) {
IDictionary<object, MappingInfo> mapping = GetMapping(httpContext);
MappingInfo mappingInfo;
if (!mapping.TryGetValue(control, out mappingInfo)) {
mappingInfo = new MappingInfo();
mapping[control] = mappingInfo;
}
return mappingInfo;
}
internal static void SetTableInMapping(HttpContextBase httpContext, object control, MetaTable table, IDictionary<string, object> defaultValues) {
MappingInfo mappingInfo = GetMappingInfo(control, httpContext);
mappingInfo.Table = table;
if (defaultValues != null) {
mappingInfo.DefaultValueMapping = new DefaultValueMapping(defaultValues);
}
}
internal static MetaTable GetTableWithFullFallback(IDataSource dataSource, HttpContextBase context) {
MetaTable table = GetTableFromMapping(context, dataSource);
if (table != null) {
return table;
}
IDynamicDataSource dynamicDataSource = dataSource as IDynamicDataSource;
if (dynamicDataSource != null) {
table = GetTableFromDynamicDataSource(dynamicDataSource);
if (table != null) {
return table;
}
}
table = DynamicDataRouteHandler.GetRequestMetaTable(context);
if (table != null) {
return table;
}
Control c = dataSource as Control;
string id = (c != null ? c.ID : String.Empty);
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
DynamicDataResources.MetaTableHelper_CantFindTable,
id));
}
internal static MetaTable GetMetaTableFromObject(object dataSource) {
IEnumerable enumerable = dataSource as IEnumerable;
if (enumerable == null) {
return null;
}
// Use the first item to determine the type
//
foreach (object o in enumerable) {
if (o != null) {
return MetaTable.GetTable(o.GetType());
}
}
return null;
}
/// Gets a table from an IDynamicDataSource's ContextType and EntitySetName.
/// Does not throw, returns null on failure.
internal static MetaTable GetTableFromDynamicDataSource(IDynamicDataSource dynamicDataSource) {
string tableName = dynamicDataSource.EntitySetName;
Type contextType = dynamicDataSource.ContextType;
if (contextType == null || String.IsNullOrEmpty(tableName)) {
return null;
}
MetaModel model;
if (MetaModel.MetaModelManager.TryGetModel(contextType, out model)) {
Debug.Assert(model != null);
MetaTable table;
if (model.TryGetTable(tableName, out table)) {
return table;
}
}
return null;
}
internal static MetaTable FindMetaTable(Control current) {
return FindMetaTable(current, HttpContext.Current.ToWrapper());
}
internal static DefaultValueMapping GetDefaultValueMapping(Control current, HttpContextBase context) {
IDictionary<object, MappingInfo> mapping = GetMapping(context);
if (!(current is INamingContainer)) {
current = current.NamingContainer;
}
for (; current != null; current = current.NamingContainer) {
MappingInfo mappingInfo;
// If we find a mapping then return that value
if (mapping.TryGetValue(current, out mappingInfo)) {
return mappingInfo.DefaultValueMapping;
}
}
return null;
}
internal static MetaTable FindMetaTable(Control current, HttpContextBase context) {
MetaTable table = null;
// Start from the first naming container
if (!(current is INamingContainer)) {
current = current.NamingContainer;
}
for (; current != null; current = current.NamingContainer) {
// Find the first table mapped to a control
table = GetTableFromMapping(context, current);
if (table != null) {
return table;
}
IDataBoundControlInterface dataBoundControl = DataControlHelper.GetDataBoundControl(current, false /*failIfNotFound*/);
// Not a data control: continue searching
if (dataBoundControl == null) {
continue;
}
IDataSource dataSourceControl = dataBoundControl.DataSourceObject;
// Check if it's associated with a DataSource or can be retrieved from the current route
if (dataSourceControl != null) {
return GetTableWithFullFallback(dataSourceControl, context);
}
// Check if it has a datasource (i.e. not a control, but directly some data)
object dataSource = dataBoundControl.DataSource;
if (dataSource != null) {
// Try to get a MetaTable from it. If so, we're done
table = GetMetaTableFromObject(dataSource);
if (table != null) {
return table;
}
}
}
return null;
}
}
}
|