public virtual bool TryBinding(IHttpContext context, IPathStack path, object controller, out IHttpHandler handler)
{
if (_handlers == null)
{
handler = null;
return false;
}
int bestIndex = -1;
int bestOverloadWeight = -1;
object[] bestParameters = null;
ActionHandler bestHandler = null;
int index = path.Index;
object[] parameters;
int overloadWeight;
foreach (ActionHandler h in _handlers)
{
if (h.Binding.TryBinding(context, path, out parameters, out overloadWeight)
&& (overloadWeight > bestOverloadWeight || (
overloadWeight == bestOverloadWeight && parameters.Length < bestParameters.Length //The fewer parameters the better if same overload weight
)) && (path.IsAtEnd || h is ParentActionHandler))
{
bestIndex = path.Index;
bestHandler = h;
bestParameters = parameters;
bestOverloadWeight = overloadWeight;
}
path.ReverseToIndex(index);
}
if (bestHandler == null)
{
handler = null;
return false;
}
// shouldTrailSlash = bestIndex == index; I.e. the best mapping hasn't used a path
if (bestIndex == index ^ path.TrailingSlash ^ DisableTrailingSlash && !(bestHandler is ParentActionHandler) && context.Request.HttpMethod == "GET")
{
// TODO: Make more efficient by simply extracting the final path section and use relative redirect: ../pathsection or ./pathsection/
IPathStack newPath = new PathStack(false);
newPath.Push(path);
newPath.TrailingSlash = !path.TrailingSlash;
context.Route.Dispose();
context.Response.Redirect("~/" + newPath.ToString(), false);
context.Response.StatusCode = 301;
context.Response.End();
}
path.ReverseToIndex(bestIndex);
if (controller == null) controller = _controllerCreator();
context.Route.AddController(controller, index); // Controller is bound, add it to the route context
handler = bestHandler.GetHttpHandler(context, controller, bestParameters);
return true;
}