public static ModelKey Parse(string value) { var key = new ModelKey(); // La clave puede llevar un índice: .customer["name"] var items = value.Trim().Split('['); // el nombre key.Name = items [0]; // el posible indice if (items.Length > 1) { key.Index = items [1].TrimEnd(']'); } return(key); }
static object GetModelValue(object model, string key, RenderModel renderModel) { if (key == ".") { return(model); } var pathItems = key.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries); var value = model; foreach (var pathItem in pathItems) { var modelKey = ModelKey.Parse(pathItem); value = GetPropertyValue(value, modelKey.Name); if (value == null) { return(null); } if (modelKey.Index != null) { string modelIndex; // Obtener el valor del indice: // es un literal si va entre comillas if (modelKey.Index[0] == '"') { modelIndex = modelKey.Index.Trim('"'); } else if (modelKey.Index[0] == '\'') { modelIndex = modelKey.Index.Trim('\''); } else if (modelKey.Index[0] == '.') { var v = GetValue(renderModel, modelKey.Index); modelIndex = v != null?v.ToString() : null; } // si no lleva . intentar tambien obtener el valor, por si es el índice de una propiedad indexada. else if (char.IsLetter(modelKey.Index[0])) { var v = GetValue(renderModel, modelKey.Index); modelIndex = v != null?v.ToString() : null; } else { modelIndex = modelKey.Index; } if (modelIndex == null) { // TODO: ¿lanzar excepción? return(null); } // si el índice por el que se accede es un número if (char.IsDigit(modelIndex[0])) { var iIndex = int.Parse(modelIndex); var list = value as IList; if (list != null) { value = list[iIndex]; } else { throw new TemplateException(string.Format( "Can't access {0} by index {1} because it is not a list", modelKey.Name, modelKey.Index)); } } else { var dic = value as IDictionary; if (dic != null) { value = dic[modelIndex]; } else { throw new TemplateException(string.Format( "Can't access {0} by index {1} because it is not a dictionary", modelKey.Name, modelKey.Index)); } } } } return(value); }