public bool TryMapping(IHttpContext context, IPathStack path) { int index = path.Index; foreach (string keyword in keywords) if (!keyword.Equals(path.Pop(), StringComparison.CurrentCultureIgnoreCase)) { path.ReverseToIndex(index); return false; } return true; }
public IHttpHandler ParseRoute(IHttpContext context, IPathStack path) { if (_controllers == null) return null; foreach (IEntryControllerBinding c in _controllers) { IHttpHandler handler; int index = path.Index; context.Route.ReverseToIndex(-1); if (c.TryBinding(context, path, out handler)) { while (handler is IParentActionHandler) if (!(handler as IParentActionHandler).TryBinding(path, out handler)) return null; return handler; } else path.ReverseToIndex(index); } return null; }
public IHttpHandler ParseRoute(IHttpContext context, IPathStack path, object controller) { IControllerBinding[] bindings = GetControllerBindings(controller.GetType()); if (bindings != null) { int index = path.Index; int controllerIndex = context.Route.Index; foreach (IControllerBinding binding in bindings) { IHttpHandler handler; if (binding.TryBinding(context, path, controller, out handler)) return handler; else { context.Route.ReverseToIndex(controllerIndex); path.ReverseToIndex(index); } } } return null; }
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; }
bool IActionBinding.TryBinding(IHttpContext context, IPathStack path, out object[] parameters, out int overloadWeight) { foreach (IMappingBinding mapping in this.Mappings) if (!mapping.TryMapping(context, path)) { parameters = null; overloadWeight = 0; return false; } // Allow IExtension to affect mapping? //foreach (IExtension extension in this.Extensions) // if (!extension.TryMapping(context, path)) // return false; overloadWeight = Mappings.Count * 10000; if (Bindings == null) { parameters = new object[0]; return true; } int l = Bindings.Length; parameters = new object[Bindings.Length]; for (int i = 0; i < l; i++) { ParamBindings pb = Bindings[i]; if (pb.IsIn) { bool bound = false; int index = path.Index; foreach (IParameterBinding bindable in pb.Bindings) { object obj; int weight; if (bindable.TryBinding(context, path, out obj, out weight)) { bool constrained = false; if (pb.Constraints != null) foreach (IBindingConstraint constraint in pb.Constraints) if (!constraint.TryConstraint(context, obj)) { constrained = true; path.ReverseToIndex(index); break; } if (!constrained) { overloadWeight += weight; parameters[i] = obj; bound = true; break; } } else { path.ReverseToIndex(index); } } if (!bound) { overloadWeight = 0; parameters = null; return false; } } } return true; }
public void Push(IPathStack path) { if (_readOnly) throw new InvalidOperationException("This PathStack is read only."); if (path == null) throw new InvalidOperationException("The PathStack cannot Push null."); int index = path.Index; path.ReverseToIndex(0); while (!path.IsAtEnd) this.Push(path.Pop()); this._trailingSlash = path.TrailingSlash; path.ReverseToIndex(index); QueryString.Add(path.QueryString); }
private bool TryBinding(IPathStack path, out object obj) { if (path.IsAtEnd) { obj = null; return false; } int index = path.Index; if (_emptyPath != null && _emptyPath.TryMapping(null, path)) { obj = _emptyValueSet ? _emptyValue : (DefaultValue != null ? DefaultValue : (BindingTargetType.IsValueType ? Activator.CreateInstance(BindingTargetType) : null)); return true; } path.ReverseToIndex(index); if (_deserializer != null) { return _deserializer(path, out obj); } else { string nextPath = path.Peek(); if (Extension != null) { if (!nextPath.EndsWith(Extension, StringComparison.CurrentCultureIgnoreCase)) { obj = null; return false; } nextPath = nextPath.Substring(0, nextPath.Length - Extension.Length); } bool f = SerializationHelper.TryDeserialize(nextPath, BindingTargetType, out obj); if (f) { path.Pop(); return true; } else return false; } }