private bool TryInvoke(MethodWrapperDescriptor method, Dictionary<string, object> allParams, ClassWrapper.ClassWrapper controllerWrapper, bool hasConverter, IHttpContext context, bool isChildRequest, out object methResult) { try { var request = context.Request; var parsValues = new List<object>(); methResult = null; var methPars = method.Parameters.ToList(); for (int index = 0; index < methPars.Count; index++) { bool parValueSet = false; var par = methPars[index]; object valueToAdd = null; if (allParams.ContainsKey(par.Name)) { var parValue = allParams[par.Name]; if (parValue.GetType() != par.ParameterType) { object convertedValue; if (UniversalTypeConverter.TryConvert(parValue, par.ParameterType, out convertedValue)) { valueToAdd = convertedValue; parValueSet = true; } else if (!par.HasDefault) { if (par.ParameterType.IsValueType) { return false; } parValueSet = true; } } else { valueToAdd = parValue; parValueSet = true; } } if (par.ParameterType == typeof(FormCollection)) { parValueSet = true; valueToAdd = new FormCollection(context.Request.Form); } if (parValueSet == false && request.ContentType != null) { var parType = par.ParameterType; if (!parType.IsValueType && !parType.IsArray && !(parType == typeof(string)) && !parType.IsEnum && !(parType == typeof(object))) { try { valueToAdd = _conversionService.Convert(parType, request.ContentType, request); parValueSet = true; } catch (Exception) { } } } if (par.HasDefault && !parValueSet) { parValueSet = true; valueToAdd = par.Default; } if (!parValueSet && string.Compare(par.Name, "returnUrl", StringComparison.OrdinalIgnoreCase) == 0) { if (request.UrlReferrer != null) { parValueSet = true; valueToAdd = request.UrlReferrer.ToString(); } } if (!par.GetType().IsValueType && !parValueSet) { parValueSet = true; valueToAdd = null; } if (!parValueSet) return false; parsValues.Add(valueToAdd); } var attributes = new List<Attribute>(method.Attributes); foreach (var attribute in attributes) { var filter = attribute as IFilter; if (filter != null) { if (!filter.OnPreExecute(context)) { methResult = NullResponse.Instance; return true; } } else if (attribute is ChildActionOnly && !isChildRequest) { throw new HttpException(404, string.Format("Url '{0}' not found.", _context.Request.Url)); } } var msd = new ModelStateDictionary(); foreach (var par in parsValues) { if (ValidationService.CanValidate(par)) { var validationResult = ValidationService.ValidateModel(par); foreach (var singleResult in validationResult) { msd.AddModelError(singleResult.Property, singleResult.Message); } } } controllerWrapper.Set("ModelState", msd); var result = controllerWrapper.TryInvoke(method, out methResult, parsValues.ToArray()); if (result) { foreach (var attribute in attributes) { var filter = attribute as IFilter; if (filter != null) { filter.OnPostExecute(context); } } } return result; } catch (Exception) { Log.Info("Not found suitable action for method '{0}'.", method.Name); methResult = null; return false; } }
private void SetupMethod(string verb, string action, MethodWrapperDescriptor method) { if (!_methods.ContainsKey(verb)) { _methods.Add(verb, new Dictionary<string, ReadOnlyCollection<MethodWrapperDescriptor>>(StringComparer.OrdinalIgnoreCase)); } if (!_methods[verb].ContainsKey(action)) { _methods[verb].Add(action, new ReadOnlyCollection<MethodWrapperDescriptor>(new List<MethodWrapperDescriptor>())); } var methods = new List<MethodWrapperDescriptor>(_methods[verb][action]); methods.Add(method); _methods[verb][action] = new ReadOnlyCollection<MethodWrapperDescriptor>(methods); }