2 // DynamicDataRouteHandler.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.Data.Linq.Mapping;
36 using System.Globalization;
37 using System.Security.Permissions;
38 using System.Security.Principal;
39 using System.Threading;
40 using System.Web.Caching;
41 using System.Web.Compilation;
42 using System.Web.Routing;
45 namespace System.Web.DynamicData
47 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
48 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
49 public class DynamicDataRouteHandler : IRouteHandler
51 static ReaderWriterLockSlim contextsLock = new ReaderWriterLockSlim ();
53 static Dictionary <HttpContext, RouteContext> contexts = new Dictionary <HttpContext, RouteContext> ();
54 Dictionary <RouteContext, IHttpHandler> handlers;
56 Dictionary <RouteContext, IHttpHandler> Handlers {
59 handlers = new Dictionary <RouteContext, IHttpHandler> ();
65 public static RequestContext GetRequestContext (HttpContext httpContext)
67 if (httpContext == null)
68 throw new ArgumentNullException ("httpContext");
73 contextsLock.EnterReadLock ();
75 if (contexts.TryGetValue (httpContext, out rc) && rc != null)
79 contextsLock.ExitReadLock ();
82 var ctxWrapper = new HttpContextWrapper (httpContext);
83 RouteData rd = RouteTable.Routes.GetRouteData (ctxWrapper);
85 rd = new RouteData ();
87 var ret = new RequestContext (ctxWrapper, rd);
91 contextsLock.EnterWriteLock ();
93 contexts.Add (httpContext, MakeRouteContext (ret, null, null, null));
96 contextsLock.ExitWriteLock ();
102 public static MetaTable GetRequestMetaTable (HttpContext httpContext)
104 if (httpContext == null)
105 throw new ArgumentNullException ("httpContext");
110 contextsLock.EnterReadLock ();
112 if (contexts.TryGetValue (httpContext, out rc) && rc != null)
116 contextsLock.ExitReadLock ();
123 public static void SetRequestMetaTable (HttpContext httpContext, MetaTable table)
125 throw new NotImplementedException ();
128 public DynamicDataRouteHandler ()
132 public MetaModel Model { get; internal set; }
135 public virtual IHttpHandler CreateHandler (DynamicDataRoute route, MetaTable table, string action)
137 var vp = String.Concat (String.Concat (HttpContext.Current.Request.ApplicationPath, "DynamicData/PageTemplates/", action, ".aspx"));
138 return (IHttpHandler) BuildManager.CreateInstanceFromVirtualPath (vp, typeof (Page));
142 protected virtual string GetCustomPageVirtualPath (MetaTable table, string viewName)
144 throw new NotImplementedException ();
148 protected virtual string GetScaffoldPageVirtualPath (MetaTable table, string viewName)
150 throw new NotImplementedException ();
153 IHttpHandler IRouteHandler.GetHttpHandler (RequestContext requestContext)
155 if (requestContext == null)
156 throw new ArgumentNullException ("requestContext");
157 RouteData rd = requestContext.RouteData;
158 var dr = rd.Route as DynamicDataRoute;
160 throw new ArgumentException ("The argument RequestContext does not have DynamicDataRoute in its RouteData");
161 string action = dr.GetActionFromRouteData (rd);
162 MetaTable mt = dr.GetTableFromRouteData (rd);
163 RouteContext rc = MakeRouteContext (requestContext, dr, action, mt);
166 Dictionary <RouteContext, IHttpHandler> handlers = Handlers;
167 if (handlers.TryGetValue (rc, out h))
169 h = CreateHandler (dr, mt, action);
170 handlers.Add (rc, h);
174 static RouteContext MakeRouteContext (RequestContext context, DynamicDataRoute route, string action, MetaTable table)
179 rd = context.RouteData;
180 route = rd.Route as DynamicDataRoute;
184 if (action == null) {
186 rd = context.RouteData;
187 action = route.GetActionFromRouteData (rd);
192 rd = context.RouteData;
194 table = route.GetTableFromRouteData (rd);
198 return new RouteContext () {
205 sealed class RouteContext
207 public DynamicDataRoute Route;
208 public string Action;
209 public MetaTable Table;
210 public RequestContext Context;
212 public RouteContext ()
216 public override bool Equals (object obj)
218 RouteContext other = obj as RouteContext;
219 return other.Route == Route & other.Action == Action && other.Table == Table && other.Context == Context;
222 public override int GetHashCode ()
224 return (Route != null ? Route.GetHashCode () << 27 : 0) +
225 (Action != null ? Action.GetHashCode () << 19 : 0) +
226 (Table != null ? Table.GetHashCode () << 9 : 0) +
227 (Context != null ? Context.GetHashCode () : 0);