/// <summary> /// invokes the action in a controller /// databindign the parameters from the propertybag /// the convetion is to user the same name /// propertybag["users"] /// action(User[] users) will be bound, while if the name in the property bag is users and /// the parameter is /// action(Users[] u) it won't /// </summary> /// <param name="controller"></param> /// <param name="actionName"></param> /// <param name="clearPropertyBagAfterDataBind"></param> public static void InvokeActionInController(Controller controller, string actionName, bool clearPropertyBagAfterDataBind) { //invoke action MethodBase action; try { action = controller.GetType().GetMethod(actionName); } catch (AmbiguousMatchException ex) { throw new AmbiguousActionNameException(controller.GetType().Name, actionName, ex); } if (action == null) throw new ActionNotFoundException(controller.GetType().Name, actionName); try { //databind parameters with the same name object[] args = DataBindParameters(controller, action); //clear property bag if (clearPropertyBagAfterDataBind) controller.PropertyBag.Clear(); //invoke action action.Invoke(controller, args); } catch (TargetInvocationException ex) { throw new ControllerActionInternalException( String.Format( "Exception invoking action {1} in controller {0}. Check the values of the parameters in the log.", controller.GetType(), actionName), ex.InnerException); // new ActionNotFoundException(String.Format("Controller {0} does not contain an action {1}",controller.GetType().Path,actionName),ex); } }
private static object[] DataBindParameters(Controller controller, MethodBase action) { ParameterInfo[] param = action.GetParameters(); object[] args = new object[param.Length]; foreach (ParameterInfo info in param) { string name = info.Name; Type type = info.ParameterType; if (controller.PropertyBag[name] != null) { // Console.WriteLine("type:"+type); // Console.WriteLine("Base:" + controller.PropertyBag[name].GetType().BaseType + " :" + controller.PropertyBag[name].GetType().BaseType.Equals(type)); // Console.WriteLine("getType:" + controller.PropertyBag[name].GetType() + " :" + controller.PropertyBag[name].GetType().Equals(type)); // Console.WriteLine("issubclass:"+controller.PropertyBag[name].GetType().IsSubclassOf(type)); if (controller.PropertyBag[name].GetType().BaseType.Equals(type) || controller.PropertyBag[name].GetType().Equals(type) || controller.PropertyBag[name].GetType().IsSubclassOf(type)) { //info.RawDefaultValue = args[info.Position] = controller.PropertyBag[name]; } } } return args; }
// [Traced(TracedAttribute.INFO)] // protected PartialView RenderPartialView(string viewName, bool fromCache) // { // PartialView p = fromCache ? (PartialView)this.partialViews[viewName] : ReinstantiatePartialView(viewName); // if (p == null) throw new ViewNotFoundException(String.Format("PartialView with name {0} not found", viewName)); // //transfer data to view, then databind // p.PropertyBag = controller.PropertyBag; // // try // { // p.DataBind(); // } // catch (Exception e) // { // throw new ViewDataBindException(String.Format("An exception {1} ocurred in DataBind method of view {0}", viewName, e), e); // } // return p; // // } protected virtual string InvokeActionInController(string controllerName, string actionName, IDictionary args, bool clearPropertyBagAfterDatabind) { //instattiate controller if (controllerName.Contains(",")) throw new AmbiguousControllerNameException( String.Format( "Controller name {0} contains ,. Are you invoiking an Update or a Navigate in the view?", controllerName), null); controller = (Controller)this.controllers[controllerName]; if (controller == null) throw new ControllerNotFoundException( String.Format( "Controller with name {0} not found in Navigator collected controllers. Are you sure it's added?", controllerName)); controller.PropertyBag = args != null ? (Hashtable)args : new Hashtable(); //invoke action controller.ViewToRender = controllerName + "/" + actionName; // MethodBase action = controller.GetType().GetMethod(actionName); // try // { // action.Invoke(controller, null); // } // catch (TargetInvocationException ex) // { // throw ex.InnerException; // } ActionInvoker.InvokeActionInController(controller, actionName, clearPropertyBagAfterDatabind); //view to render return controller.ViewToRender; }
/// <summary> /// invokes the action in a controller /// databindign the parameters from the propertybag /// the convetion is to user the same name /// propertybag["users"] /// action(User[] users) will be bound, while if the name in the property bag is users and /// the parameter is /// action(Users[] u) it won't /// </summary> /// <param name="controller"></param> /// <param name="actionName"></param> public static void InvokeActionInController(Controller controller, string actionName) { InvokeActionInController(controller, actionName, true); }