Entity ForEach [JsonIgnore] - PullRequest
       7

Entity ForEach [JsonIgnore]

0 голосов
/ 26 января 2019

У меня может быть 60-70 классов, каждый из которых имеет различные столбцы Id, которые я хотел бы исключить, когда я возвращаю данные JSON из Web API.Внутренне я присоединяюсь по Id, но все, что обращено вперед, использует Guid.Итак, мой первичный ключ - это Id (int), а затем есть Guid для внешнего мира, чтобы сделать его более безопасным.

Как правило, вы просто добавляете [JsonIgnore] поверх свойства, и он заботится оэто, но у меня есть много классов, которые могут обновляться время от времени.Всякий раз, когда я зачищаю все и принудительно перезаписываю, он удаляет мои изменения.

Вместо ручного добавления [JsonIgnore] в каждый столбец Id, который я хочу исключить, кажется более логичным просто обрабатывать это в OnModelCreating.Я могу циклически просматривать свойства и использовать .Ignore, но это также удаляет свойство из всего остального.Я просто не хочу, чтобы он сериализовал и возвратил ни один из столбцов с именем «Id» и любые внешние ключи (которые также являются Ids).

Итак, вот пример из одного класса

[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; }

Я могу «заставить это работать» трудным путем, но я надеюсь, что есть быстрый и простой способ достичь тех же результатов, чтобы я мог тратить время на важные части.

РЕДАКТИРОВАТЬ: Вот что возвращает данные пользователю.

// GET: api/Distributors
[HttpGet]
public async Task<ActionResult<IEnumerable<Distributor>>> GetDistributor()
{
    return await _context.Distributor.ToListAsync();
}

1 Ответ

0 голосов
/ 26 января 2019

Вы можете написать свой собственный DefaultContractResolver , чтобы исключить любое свойство, которое вы хотите в процессе сериализации.

Ниже приведен пример для него:

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;
        }
    }

затемВы должны настроить это в вашем Startup.cs в ConfigureServices, как показано ниже

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc()
                .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new PropertyIgnoringContractResolver());
        }

Однако, что я на самом деле сделал бы, так это то, что я создал бы DTO ответа, чтобы соответствовать потребностям моих ответов API.Вместо возврата необработанных типов сущностей.Например;

[HttpGet]
public async Task<ActionResult<IEnumerable<Distributor>>> GetDistributor()
{
   return await _context.Distributor.Select(dist => new DistributorDTO 
   {
     Name = dist.Name,
     // so on..
   }).ToListAsync();
}

Реализуя что-то подобное, вы также оптимизируете запросы к базе данных, выбрав только те свойства, которые требуются для ответа API.

...