/// <summary> /// Initializes a new instance of the <see cref="ControllerDirector"/> class. /// </summary> /// <param name="controller">Controller to handle.</param> public ControllerDirector(Controller controller) { _controllerPrototype = controller; _type = controller.GetType(); FindControllerName(_type); //controller.ControllerUri = _uri; //controller.ControllerName = _name; Type actionResultType = typeof (IActionResult); Type viewDataType = typeof (IViewData); MethodInfo indexMethod = null; foreach (MethodInfo methodInfo in _type.GetMethods(BindingFlags.Instance | BindingFlags.Public)) { if (methodInfo.IsAbstract) continue; if (methodInfo.Name.StartsWith("get_") || methodInfo.Name.StartsWith("set_")) continue; if (methodInfo.DeclaringType == typeof (Controller)) continue; if (methodInfo.GetParameters().Length > 0) continue; if (methodInfo.ReturnType == actionResultType) MapMethod(methodInfo); if (methodInfo.ReturnType == viewDataType) MapMethod(methodInfo); if (methodInfo.Name.ToLower() == "index" && methodInfo.GetParameters().Length == 0 && (methodInfo.ReturnType == actionResultType || methodInfo.ReturnType == viewDataType)) indexMethod = methodInfo; CheckIfDefaultMethod(methodInfo); } // use "Index" method if no other default method have been specified. if (_defaultMethod == null && indexMethod != null) _defaultMethod = indexMethod; }
/// <summary> /// Enqueue a used controller. /// </summary> /// <param name="controller">Controller to enqueue</param> public void Enqueue(Controller controller) { lock (_createdControllers) _createdControllers.Enqueue(controller); }
/// <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; } }
/// <summary> /// Trigger the InvokingAction event. /// </summary> /// <param name="controller"></param> /// <param name="method"></param> /// <param name="context"></param> /// <remarks> /// <para> /// We need to capture all exceptions since we have no control /// over what the event subscribers do, and we do not want the /// whole server to crash because of an unhandled exception. /// </para> /// <para> /// HttpExceptions are a different story since they are handled /// in a lower level in the framework. /// </para> /// </remarks> /// <exception cref="Exception">A HTTP exception has been thrown by an event subscriber.</exception> private void InvokeEvent(Controller controller, MethodInfo method, RequestContext context) { try { InvokingAction(this, new ControllerEventArgs(controller, method.Name.ToLower(), context)); } catch (Exception err) { if (err is HttpException) throw; _logger.Error("Event threw exception: " + err); } }
public DirectorContext(ControllerDirector director, Controller controller) { Director = director; Controller = controller; }