public static void Run(dynamic page, object controller)
{
Assert.IsTrue(page != null);
IList<string> urlData = page.UrlData;
urlData = urlData.Where(s=>!string.IsNullOrWhiteSpace(s)).Skip(1).ToList();
var action = urlData.Count() > 0 ? urlData[0].ToLower() : "";
var cacheKey = controller.ToString();
IList<RouteAttribute> routes = null;
if (cache.ContainsKey(cacheKey))
{
routes = cache[cacheKey] as IList<RouteAttribute>;
}
else
{
routes = new List<RouteAttribute>();
var methods = controller.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance);
foreach (var method in methods)
{
foreach (var attr in method.GetCustomAttributes(typeof(RouteAttribute), true))
{
((RouteAttribute)attr).Method = method;
routes.Add((RouteAttribute)attr);
}
}
//not to cache, if web.config says debug=true
//if (!HttpContext.Current.IsDebuggingEnabled) cache[cacheKey] = routes;
if (!page.Context.IsDebuggingEnabled) cache[cacheKey] = routes;
}
var rs = routes.Where(r => string.Compare(r.Action, action, true) == 0);
if (rs.Count() == 0)
{
rs = urlData.Count == 0 ?
routes.Where(r => r.Action == "/") :
routes.Where(r => r.Action == "/*");
}
var route = rs.Where(r => r.IsPost == page.IsPost).FirstOrDefault();
//if (route == null) route = routes.Where(r => r.Action == "*").FirstOrDefault();
if (route != null && route.Method != null)
{
Log.Write("Controller: Run Action {0} -> {1}", action, route.Action);
try
{
var parameters = route.Method.GetParameters();
if(parameters==null || parameters.Length ==0)
{
HandleResult(page, route.Method.Invoke(controller, null));
}
else
{
var objects = new object[parameters.Length];
for(int i=0; i<parameters.Length; i++)
{
if(parameters[i].ParameterType == typeof(string[]))
{
objects[i] = urlData.ToArray();
}
else if(parameters[i].ParameterType == typeof(string))
{
//action name removed
objects[i] = string.Join("/", urlData.ToArray(), 1, urlData.Count() - 1);
}
else if (parameters[i].Name == "form" ||
parameters[i].ParameterType == typeof(NameValueCollection))
{
objects[i] = page.Request.Form;
}
else if (parameters[i].Name=="request" ||
parameters[i].ParameterType == typeof(HttpRequest))
{
objects[i] = page.Request;
}
}
HandleResult(page, route.Method.Invoke(controller, objects));
}
}
catch (TargetInvocationException ex)
{
throw ex.InnerException;
}
}
else
{
throw new Exception(string.Format("Controller: Cannot Find Action {0}", action));
}
}