Using the dynamic
type, the ExpandoObject
class that supports IDictionary<string, object>
to add the properties at run time ... You can start your implementation with the example below.
public class PessoasController : ApiController
{
public IEnumerable<object> Get(string exibir = "")
{
//Consulta ao repositório, simulada.
var lista = new List<PessoaViewModel>
{
new PessoaViewModel{ Id = 1, Nome="Nome 1", Sobrenome = "Sobrenome 1" },
new PessoaViewModel{ Id = 2, Nome="Nome 2", Sobrenome = "Sobrenome 2" },
new PessoaViewModel{ Id = 3, Nome="Nome 3", Sobrenome = "Sobrenome 3" }
};
//faz o split pelo separador
var queryFilter = exibir.Split(',');
if (string.IsNullOrWhiteSpace(exibir) && queryFilter.Length <= 0)
{
return lista;
}
else{
// Utilizando reflection retorna apenas as propriedades informadas no filtro,
// que existem no objeto comparação.
var propriedades = typeof(PessoaViewModel)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(x => queryFilter.Select(q => q.ToLower()).Contains(x.Name.ToLower()))
.ToList();
// Se as propriedades de filtro não batem com o modelo, retorna o objeto inteiro
if (propriedades.Count() == 0)
return lista;
// Aqui é a onde a mágica acontece, utilizando o ExpandoObject,
// criamos um dicionário armazenando o nome e valor daquelas
// propriedades que existem, de fato, na classe.
var output = lista.Select(registro =>
{
dynamic x = new ExpandoObject();
var temp = x as IDictionary<string, object>;
foreach (var prop in propriedades)
temp.Add(prop.Name, prop.GetValue(registro));
return x;
});
return output;
}
}
}
Demo:
Reference:
Building C # objects dynamically - O'Reilly Media