IAsyncResult IController.BeginExecute(ActionInvocation action, AsyncCallback callback, object asyncState) { if (action == null) { throw new ArgumentNullException("action"); } if (callback == null) { throw new ArgumentNullException("callback"); } if (_asyncResult != null) { throw new InvalidOperationException(); } _action = action; ActionDescriptor actionDescriptor = ControllerDescriptor.GetAction(this, action.ActionName); if (actionDescriptor == null) { throw new InvalidOperationException(); } if (actionDescriptor.IsAsync) { _asyncResult = new ActionAsyncResult(this, callback, asyncState); try { Async<ActionResult> asyncActionResult = (Async<ActionResult>)actionDescriptor.Invoke(this, action); if (String.IsNullOrEmpty(asyncActionResult.Message)) { asyncActionResult.Message = "Navigating"; } asyncActionResult.Completed += OnActionCompleted; } catch (Exception e) { _asyncResult = new ActionAsyncResult(new ErrorActionResult(e), asyncState); callback(_asyncResult); } } else { ActionResult result; try { result = (ActionResult)actionDescriptor.Invoke(this, action); } catch (Exception e) { result = new ErrorActionResult(e); } _asyncResult = new ActionAsyncResult(result, asyncState); callback(_asyncResult); } return _asyncResult; }
public object Invoke(Controller controller, ActionInvocation action) { ParameterInfo[] parameters = _actionMethod.GetParameters(); object[] parameterValues = null; if (parameters.Length != 0) { List<object> parameterList = new List<object>(parameters.Length); int paramIndex = 0; for (; paramIndex < action.Parameters.Count && paramIndex < parameters.Length; paramIndex++) { parameterList.Add(action.Parameters[paramIndex]); } for (; paramIndex < parameters.Length; paramIndex++) { string paramName = parameters[paramIndex].Name; string paramValue = null; action.NamedParameters.TryGetValue(paramName, out paramValue); parameterList.Add(paramValue); } for (int i = 0; i < parameterList.Count; i++) { Type parameterType = parameters[i].ParameterType; object paramValue = parameterList[i]; if ((paramValue == null) || (parameterType.IsAssignableFrom(paramValue.GetType()) == false)) { paramValue = Convert.ChangeType(paramValue, parameterType, CultureInfo.CurrentCulture); parameterList[i] = paramValue; } } parameterValues = parameterList.ToArray(); } return _actionMethod.Invoke(controller, parameterValues); }
/// <internalonly /> protected override IAsyncResult BeginLoadUri(Uri uri, Page uriContext, AsyncCallback callback, object asyncState) { if (_currentController != null) { throw new InvalidOperationException(); } UriData uriData = new UriData(uri); IList<string> path = uriData.GetPath(); int minimumCount = _controllerType != null ? 1 : 2; if ((path != null) && (path.Count >= minimumCount)) { Controller controller = null; Type controllerType = _controllerType; if (controllerType == null) { Type appType = Application.Current.GetType(); _currentControllerName = path[0]; path.RemoveAt(0); string controllerTypeName = appType.Namespace + ".Controllers." + _currentControllerName + "Controller"; controllerType = appType.Assembly.GetType(controllerTypeName, /* throwOnError */ false); if (typeof(Controller).IsAssignableFrom(controllerType) == false) { controllerType = null; } } if (controllerType != null) { controller = CreateController(controllerType); } if (controller != null) { _currentController = controller; _currentActionName = path[0]; path.RemoveAt(0); ActionInvocation action = new ActionInvocation(_currentActionName); foreach (string parameterItem in path) { action.Parameters.Add(parameterItem); } IDictionary<string, string> queryString = uriData.GetQueryString(); if (queryString != null) { foreach (KeyValuePair<string, string> parameterItem in queryString) { action.NamedParameters[parameterItem.Key] = parameterItem.Value; } } return ((IController)controller).BeginExecute(action, callback, asyncState); } } return base.BeginLoadUri(uri, uriContext, callback, asyncState); }