Ho forse 60-70 classi che hanno tutte diverse colonne Id che vorrei escludere quando restituisco i dati JSON dall'API Web. Internamente mi unisco a Id, ma qualsiasi cosa frontalmente faccia uso di un Guid. Quindi la mia chiave primaria è l'Id (int) e poi c'è un Guid lì per il mondo esterno da utilizzare per rendere le cose più sicure.
Solitamente si aggiunge [JsonIgnore] alla proprietà e ci si prende cura di esso, ma ho un sacco di classi che possono essere aggiornate di volta in volta. Ogni volta che impacchetta tutto e costringo a sovrascrivere, rimuoverò le mie modifiche.
Invece di aggiungere manualmente [JsonIgnore] a ogni colonna Id che voglio escludere, sembra più logico gestirlo solo in OnModelCreating. Sono in grado di scorrere le proprietà e utilizzare. Ignora, ma rimuove la proprietà da qualsiasi altra cosa. Semplicemente non voglio che si serializzi e restituisca nessuna delle colonne denominate "Id" e le eventuali chiavi esterne (che sono anche Id).
Quindi ecco un esempio di una classe
[JsonIgnore]
public int Id { get; set; }
public Guid Guid { get; set; }
public string Name { get; set; }
public bool? Active { get; set; }
[JsonIgnore]
public int HoldTypeId { get; set; }
public DateTime CreateDateTime { get; set; }
public DateTime UpdateDateTime { get; set; }
Posso "farlo funzionare" nel modo più duro, ma spero che ci sia un modo semplice e veloce per ottenere gli stessi risultati, così posso dedicare tempo ai pezzi importanti.
EDIT: Ecco cosa sta restituendo i dati all'utente.
// GET: api/Distributors
[HttpGet]
public async Task<ActionResult<IEnumerable<Distributor>>> GetDistributor()
{
return await _context.Distributor.ToListAsync();
}
È possibile scrivere il proprio DefaultContractResolver per escludere qualsiasi proprietà che si desidera sul processo di serializzazione.
Di seguito c'è un esempio per questo:
public class PropertyIgnoringContractResolver : DefaultContractResolver
{
private readonly Dictionary<Type, string[]> _ignoredPropertiesContainer = new Dictionary<Type, string[]>
{
// for type student, we would like to ignore Id and SchooldId properties.
{ typeof(Student), new string[] { "Id", "SchoolId" } }
};
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
string[] ignoredPropertiesOfType;
if (this._ignoredPropertiesContainer.TryGetValue(member.DeclaringType, out ignoredPropertiesOfType))
{
if (ignoredPropertiesOfType.Contains(member.Name))
{
property.ShouldSerialize = instance => false;
// Also you could add ShouldDeserialize here as well if you want.
return property;
}
}
return property;
}
}
allora dovresti configurarlo nel tuo Startup.cs
in ConfigureServices
come sotto
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddJsonOptions(options => options.SerializerSettings.ContractResolver = new PropertyIgnoringContractResolver());
}
Tuttavia, quello che effettivamente farei è che creerei DTO di risposta per soddisfare le esigenze delle mie risposte API. Invece di restituire tipi di entità non elaborati. Piace;
[HttpGet]
public async Task<ActionResult<IEnumerable<Distributor>>> GetDistributor()
{
return await _context.Distributor.Select(dist => new DistributorDTO
{
Name = dist.Name,
// so on..
}).ToListAsync();
}
Implementando qualcosa di simile, si ottimizzano anche le query del database selezionando solo le proprietà richieste dalla risposta API.