/// <summary> /// Invokes the specified method information. /// <remarks> /// Invoke action would regard to method parameter to use difference logic. Following steps show the IF-ELSE case. When it is hit, other would not go through. /// <list type="number"><item> /// If input parameter count is 0, invoke without parameter object. /// </item><item> /// If input parameter count is 1 and key is not empty or null, invoke using key. /// </item><item> /// If input parameter count is 1 and key is empty or null, invoke using key, try to get JSON object from request body and convert to object for invoke. /// </item><item> /// If input parameter count more than 1, try read JSON data to match parameters by name (ignore case) in root level, then invoke. /// </item></list></remarks></summary> /// <param name="instance">The instance.</param> /// <param name="methodInfo">The method information.</param> /// <param name="httpRequest">The HTTP request.</param> /// <param name="key">The key.</param> /// <param name="jsonBody">The json body.</param> /// <returns>System.Object.</returns> protected virtual object Invoke(object instance, MethodInfo methodInfo, HttpRequest httpRequest, string key, out string jsonBody) { var inputParameters = methodInfo.GetParameters(); jsonBody = null; if (!string.IsNullOrWhiteSpace(key) && key.Contains('%')) { key = key.ToUrlDecodedText(); } if (inputParameters.Length == 0) { return methodInfo.Invoke(instance, null); } else if (inputParameters.Length == 1) { if (!string.IsNullOrWhiteSpace(key) && (inputParameters[0].ParameterType == typeof(string) || inputParameters[0].ParameterType.IsValueType)) { return methodInfo.Invoke(instance, new object[] { ReflectionExtension.ConvertToObjectByType(inputParameters[0].ParameterType, key) }); } else { var json = jsonBody = httpRequest.GetPostJson(Encoding.UTF8); return methodInfo.Invoke(instance, new object[] { DeserializeJsonObject(json, inputParameters[0].ParameterType) }); } } else { object[] parameters = new object[inputParameters.Length]; if (httpRequest.QueryString.Count > 0) { var start = 1; if (!string.IsNullOrWhiteSpace(key) && (inputParameters[0].ParameterType.TryGetNullableType().IsValueType)) { parameters[0] = ReflectionExtension.ConvertToObjectByType(inputParameters[0].ParameterType, key); } else { var json = jsonBody = httpRequest.GetPostJson(Encoding.UTF8); parameters[0] = json.TryConvertJsonToObject(); if (parameters[0] == null) { start = 0; } } for (var i = start; i < inputParameters.Length; i++) { parameters[i] = ReflectionExtension.ConvertToObjectByType(inputParameters[i].ParameterType, httpRequest.QueryString.Get(inputParameters[i].Name)); } } else { var json = jsonBody = httpRequest.GetPostJson(Encoding.UTF8); var jsonObject = string.IsNullOrWhiteSpace(json) ? null : JObject.Parse(json); if (jsonObject != null) { for (int i = 0; i < inputParameters.Length; i++) { var jTokenObject = jsonObject.GetProperty(inputParameters[i].Name); parameters[i] = jTokenObject == null ? null : jTokenObject.ToObject(inputParameters[i].ParameterType); } } } return methodInfo.Invoke(instance, parameters); } }