/// <summary> /// Invoke method on given type /// </summary> internal protected void InvokeMethod(Type hostType) { string methodName = base["method"]; string result = string.Empty; if (string.IsNullOrEmpty(methodName)) { this.Response.AddError("No method specified for \"{0}\"", hostType.Name); this.Response.Abort(); return; } MethodInfo methodInfo = WebInvokable.GetMethod(hostType, methodName); if (methodInfo == null) { this.Response.AddError("Invokable method \"{0}()\" not found in type \"{1}\"", methodName, hostType.Name); this.Response.Abort(); return; } // convert parameter types string value; ParameterInfo[] info = methodInfo.GetParameters(); List <object> arguments = new List <object>(); try { foreach (ParameterInfo p in info) { value = this.Parameters[p.Name]; arguments.Add(EcmaScript.ToType(value, p.ParameterType, this.Context)); } } catch (System.Exception ex) { Idaho.Exception.Log(ex); this.Response.Error(ex); return; } try { object instance = methodInfo.IsStatic ? null : this.CreateInstance(hostType); result = methodInfo.Invoke(instance, arguments.ToArray()).ToJSON(); } catch (System.Exception ex) { Idaho.Exception.Log(ex); this.Response.Error(ex); } finally { this.Response.Complete(result, false); } }
/// <summary> /// Infer constructor parameter values /// </summary> /// <remarks> /// If unable to infer a parameter, return null. Note that this will need /// to be evaluated differently from a constructor with no parameters, /// which will be an empty list rather than null. /// </remarks> private object[] InferParameters(ConstructorInfo i) { List <object> parameters = new List <object>(); ParameterInfo[] info = i.GetParameters(); object value = null; foreach (ParameterInfo p in info) { value = EcmaScript.ToType(string.Empty, p.ParameterType, this.Context); if (value != null) { parameters.Add(value); } else { return(null); } } return(parameters.ToArray()); }
/// <summary> /// Use reflection to render requested control /// </summary> internal override void Process() { if (!this.Response.WriteCache(this.Key)) { string typeName = base["type"]; StringBuilder sb = new StringBuilder(); HtmlTextWriter writer = new HtmlTextWriter(new StringWriter(sb)); IAjaxControl control; PropertyInfo[] properties; System.Type controlType; if (string.IsNullOrEmpty(typeName)) { this.Response.AddError("No control specified"); return; } // expand abbreviated type names typeName = AjaxBase.Expand(typeName); // get control type and validate if (Handlers.AjaxHandler.KnownType.ContainsKey(typeName)) { controlType = Handlers.AjaxHandler.KnownType[typeName]; } else { controlType = System.Type.GetType(typeName); } if (controlType == null) { this.Response.AddError("Control \"{0}\" could not found", typeName); return; } if (!this.ValidType(controlType)) { this.Response.AddError("Control \"{0}\" cannot be called asynchronously", typeName); return; } // now that validated, create instance and set properties using (Page page = new Page(this.Context)) { control = (IAjaxControl)page.LoadControl(controlType, null); } properties = WebBindable.Properties(controlType); try { foreach (PropertyInfo p in properties) { // only set properties for which a value has been passed if (!string.IsNullOrEmpty(this.Parameters[p.Name])) { p.SetValue(control, EcmaScript.ToType( this.Parameters[p.Name], p.PropertyType, this.Context), null); } } // set ID so generated JavaScript references are equivalent if (!string.IsNullOrEmpty(this.Parameters["id"])) { control.ID = this.Parameters["id"]; } if (!string.IsNullOrEmpty(this.Parameters["style"])) { control.CssStyle = this.Parameters["style"]; } if (!string.IsNullOrEmpty(this.Parameters["cssClass"])) { control.CssClass = this.Parameters["cssClass"]; } control.Ajax.Context = this.Context; // any control rendered by this method is isolated from // the normal page life cycle control.Ajax.RenderState = AjaxBase.RenderStates.Isolation; control.Ajax.RenderMode = AjaxBase.RenderModes.Asynchronous; control.RenderControl(writer); } catch (System.Exception ex) { Idaho.Exception.Log(ex); control.Ajax.Cacheable = false; this.Response.Error(ex); } finally { this.Response.Cacheable = control.Ajax.Cacheable; this.Response.CacheDependencies = control.Ajax.DependsOnType; this.Response.CacheKey = this.Key; this.Response.Complete(sb.ToString(), true); } } }