예제 #1
0
        /// <summary>
        /// Get a cached controller or create a new one.
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// We need to have one controller per simultaneous request since
        /// all properties used in the controller will otherwise get overwritten
        /// each time a new request is invoked.
        /// </remarks>
        private Controller CreateController()
        {
            Controller controller = null;

            lock (_createdControllers)
            {
                if (_createdControllers.Count > 0)
                {
                    controller = _createdControllers.Dequeue();
                }
            }

            if (controller == null)
            {
                controller = (Controller)_controllerPrototype.Clone();
                //controller.ControllerUri = _uri;
                //controller.ControllerName = _name;
            }

            controller.Clear();
            return(controller);
        }
예제 #2
0
        /// <summary>
        /// Process controller request.
        /// </summary>
        /// <param name="context">Controller context</param>
        /// <param name="controller">Controller used to process request</param>
        /// <returns>Action result.</returns>
        /// <exception cref="NotFoundException"><c>NotFoundException</c>.</exception>
        /// <exception cref="InvalidOperationException">Specified URI is not for this controller.</exception>
        /// <remarks>
        /// Controller is returned as a parameter to let us be able to use it as a variable
        /// in the view. It's VERY important <see cref="Enqueue"/> is called when rendering is complete (or if an exception
        /// is thrown).
        /// </remarks>
        public object Process(IControllerContext context, out Controller controller)
        {
            if (!context.Uri.AbsolutePath.StartsWith(_uri))
            {
                throw new InvalidOperationException("Uri '" + context.Uri + "' is not for controller '" + _type.FullName +
                                                    "'.");
            }
            controller = null;
            MethodInfo method;

            if (context.UriSegments.Length < _uriSegments)
            {
                throw new NotFoundException("No action specified for controller '" + _uri + "'.");
            }

            // using default action
            if (context.UriSegments.Length == _uriSegments)
            {
                if (_defaultMethod == null)
                {
                    return(null);
                }
                method = _defaultMethod;
            }
            else
            {
                string actionName = context.UriSegments[_uriSegments];
                method = GetMethod(context.RequestContext.Request.Method, actionName);
                if (method == null)
                {
                    return(null);
                }
            }

            context.ControllerUri  = _uri;
            context.ControllerName = _name;
            context.ActionName     = context.ActionName = method.Name.ToLower();

            // invoke method
            controller = CreateController();
            try
            {
                controller.Clear();
                InvokeEvent(controller, method, context.RequestContext);
                controller.SetContext(context);

                // Before action can filter out stuff.
                var actionResult = controller.InvokeBeforeAction(method);
                if (actionResult != null)
                {
                    return(actionResult);
                }

                var result = method.Invoke(controller, null);
                context.Title      = controller.Title;
                context.LayoutName = controller.LayoutName;
                controller.InvokeAfterAction((IActionResult)result);
                return(result);
            }
            catch (Exception err)
            {
                var result = controller.TriggerOnException(err);
                if (result == null)
                {
                    Enqueue(controller);
                    throw;
                }

                controller.InvokeAfterAction(result);
                return(result);
            }
        }
예제 #3
0
        /// <summary>
        /// Process controller request.
        /// </summary>
        /// <param name="context">Controller context</param>
        /// <param name="controller">Controller used to process request</param>
        /// <returns>Action result.</returns>
        /// <exception cref="NotFoundException"><c>NotFoundException</c>.</exception>
        /// <exception cref="InvalidOperationException">Specified URI is not for this controller.</exception>
        /// <remarks>
        /// Controller is returned as a parameter to let us be able to use it as a variable
        /// in the view. It's VERY important <see cref="Enqueue"/> is called when rendering is complete (or if an exception
        /// is thrown).
        /// </remarks>
        public object Process(IControllerContext context, out Controller controller)
        {
            if (!context.Uri.AbsolutePath.StartsWith(_uri))
                throw new InvalidOperationException("Uri '" + context.Uri + "' is not for controller '" + _type.FullName +
                                                    "'.");
            controller = null;
            MethodInfo method;

            if (context.UriSegments.Length < _uriSegments)
                throw new NotFoundException("No action specified for controller '" + _uri + "'.");

            // using default action
            if (context.UriSegments.Length == _uriSegments)
            {
                if (_defaultMethod == null)
                    return null;
                method = _defaultMethod;
            }
            else
            {
                string actionName = context.UriSegments[_uriSegments];
                method = GetMethod(context.RequestContext.Request.Method, actionName);
                if (method == null)
                    return null;
            }

            context.ControllerUri = _uri;
            context.ControllerName = _name;
            context.ActionName = context.ActionName = method.Name.ToLower();

            // invoke method
            controller = CreateController();
            try
            {
                controller.Clear();
                InvokeEvent(controller, method, context.RequestContext);
                controller.SetContext(context);

                // Before action can filter out stuff.
                var actionResult = controller.InvokeBeforeAction(method);
                if (actionResult != null)
                    return actionResult;

                var result = method.Invoke(controller, null);
                context.Title = controller.Title;
                context.LayoutName = controller.LayoutName;
                controller.InvokeAfterAction((IActionResult)result);
                return result;
            }
            catch (Exception err)
            {
                var result = controller.TriggerOnException(err);
                if (result == null)
                {
                    Enqueue(controller);
                    throw;
                }

                controller.InvokeAfterAction(result);
                return result;
            }
        }