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;
		}
Пример #6
0
		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);
		}
Пример #7
0
		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;
			}
		}