private ModelBindingModel GetModel(Stack <ModelBindingModel> stack, string parameter) { ModelBindingModel model; if (stack.Any()) { model = stack.Peek(); if (model.ParameterName.Equals(parameter)) { return(model); } } model = new ModelBindingModel(parameter); stack.Push(model); return(model); }
public IActionResult UltimateModelBinding( ModelBindingModel model, [FromServices] IUrlHelperFactory urlHelper) { return(null); }
private ModelBindingModel GetModel(Stack <ModelBindingModel> stack, string parameter) { ModelBindingModel model; if (stack.Any()) { model = stack.Peek(); if (model.ParameterName.Equals(parameter)) { return(model); } else if ((model.ParameterName + "[0].key").Equals(parameter) || (model.ParameterName + ".index").Equals(parameter)) { // we skip these special dictionary related model entries and return a "throw-away" model, meaning that we won't add it to the stack return(new ModelBindingModel(parameter)); } else { // although the name of the last one on the stack doesn't seem to match the parameter, it's still possible // that the model we need is there. This can happen when dictionaries and arrays are involved, since adding keys to // those, will result in adding that key/index as a model and later that model is bound, but it will never be // bound as a property, since it isn't one. This means that those keys/indexes will never be popped of the stack and added // to their model being the dictionary/array. So we need to move through the stack as long as the name of the model // preceding it start with "{ParameterName}." or "{ParameterName}[digits}" in case we are dealing with an array // and adding all those intermediate models as "properties" until we reach the model we are looking for string regexPattern = string.Format(@"^{0}\..+|^{0}\[\d+\]", parameter); Regex regex = new Regex(regexPattern, RegexOptions.Compiled); if (regex.IsMatch(model.ParameterName)) { List <ModelBindingModel> possiblePropertiesOfRequestedModel = new List <ModelBindingModel>(); model = stack.Pop(); while (regex.IsMatch(model.ParameterName)) { possiblePropertiesOfRequestedModel.Insert(0, model); model = stack.Pop(); } // The model we have now should be the one we were looking for in the first place if (model.ParameterName.Equals(parameter)) { foreach (var modelProperty in possiblePropertiesOfRequestedModel) { model.Properties.Add(modelProperty); } stack.Push(model); // we put the requested model back on the stack as if it was found there in the first place return(model); } else // This should not happen, but in case it does, we undo our popping above { foreach (var possiblePropertyOfRequestedModel in possiblePropertiesOfRequestedModel) { stack.Push(possiblePropertyOfRequestedModel); } stack.Push(model); // we put the requested model back on the stack as if it was found there in the first place } } } } model = new ModelBindingModel(parameter); stack.Push(model); return(model); }