Возвращает только полезные поля из API

#c# #asp.net-core-webapi

#c# #asp.net-core-webapi

Вопрос:

Как применить фильтрацию JSON в ответ в .net core webapi

У меня есть конечная точка, которая использует HTTP Get verb и возвращает более 80 полей в JSON, но я хочу возвращать только те поля, которые запрашиваются клиентом на основе некоторых условий where. Не понимаю, как реализовать то же самое и как передавать параметры для селектора и фильтрации от клиента (postman, swagger). Любое быстрое предложение или примерное решение будет полезно для реализации того же самого.

 [HttpGet]
[Route("api/v1/cards")]
public IActionResult Cards(inputParameters,selector,filtering)
{
return OK(----)
}
  

В селекторе клиент передает поля, которые он хочет получить в ответ, а в клиенте фильтрации передает параметр для условия where

Комментарии:

1. Не могли бы вы привести пример selector ?

2. Вы могли бы заглянуть в GraphQL. «Это язык запросов для API и среда выполнения для выполнения этих запросов с вашими существующими данными. GraphQL предоставляет полное и понятное описание данных в вашем API, дает клиентам возможность запрашивать именно то, что им нужно, и ничего больше, упрощает разработку API с течением времени и предоставляет мощные инструменты разработчика «.

3. OData является конкурирующим стандартом с GraphQL и предоставляет те же функции. Если вы используете Entity Framework, вам понравится глубочайшая интеграция с ним с помощью OData. GraphQL является более универсальным, поэтому потребует больше усилий для настройки, но также может работать с другими поставщиками данных и источниками. Любой из них является хорошим вариантом и позволит получить то, что вы ищете.

4. @Haytam поля, которые клиент хочет получить в ответ, например, я возвращаю объект student, у которого есть 5 полей (Id, Name, DOB, адрес, Тема) но в запросе клиенту нужны только два поля (Name и DOB), в другом запросе ему нужны три поля (Subject, Id, Address) и так далее ..

5. Да. Тогда вам определенно нужен либо OData, либо GraphQL.

Ответ №1:

Создайте ViewModel и верните его в нем.

Например:

 public class ViewModel
{
    public string Property1 { get; set; }

    public string Property2 { get; set; }

    public int Property3 { get; set; }
}
  

И затем в вашем GET действии:

 [HttpGet]
[Route("api/v1/cards")]
public IActionResult Cards(inputParameters,selector,filtering)
{
    return OK(new ViewModel 
           { 
                Property1 = FromJson.Something, 
                Property2 = FromJson.Something44, 
                Property3 = FromJson.Something79 
           });
}
  

С помощью классов моделей просмотра вы можете возвращать значения в JSON стиле со свойствами, которые вы хотите.

Ответ №2:

Вы можете использовать библиотеку Automapper и сопоставить модель с ViewModel, установив класс профиля сопоставления.

Сначала добавьте пакеты Automapper и Automapper dependency injection.

Затем добавьте Automapper в класс startup:

     public class Startup
{
    // Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        ...
Mapper.Reset(); // Useful if you're using code-first and migrations.
services.AddAutomapper();
    }

    // Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app)
    {
        ...
    }
}
  

Создайте свою ViewModel, содержащую только необходимые свойства для отправки во внешнее приложение.

 public class CardViewModel
{
public object PropVM1 {get; set;}
public object PropVM2 {get; set;}
public object PropVM3 {get; set;}
...
}
  

Из класса модели:

 public class Card
    {
    public object Prop1 {get; set;}
    public object Prop2 {get; set;}
    public object Prop3 {get; set;}
    public object Prop4 {get; set;}
    public object Prop5 {get; set;}
    ...
    }
  

Затем создайте класс профиля сопоставления, который наследуется от AutoMapper.Профиль:

 public class AppMappingProfile : Profile
{
public AppMappingProfile()
{
CreateMap<Card, CardViewModel>()
   .ForMember(d => d.PropVM1, ex => ex.MapFrom(o => o.Prop1))
   .ForMember(d => d.PropVM2, ex => ex.MapFrom(o => o.Prop2))
   .ForMember(d => d.PropVM3, ex => ex.MapFrom(o => o.Prop3))
   .ReverseMap() // if a two-away Mapping is necessary
}
} 
  

Наконец, добавьте Automapper в свой контроллер:

 public class CardController : Controller
{
private readonly IMapper;
public CardController(IMapper mapper)
{
_mapper = mapper;
}
[HttpGet]
[Route("api/v1/cards")]
public IActionResult Cards(inputParameters,selector,filtering)
{
var result = DoYourThing();

//if a list of cards
if(result != null amp;amp; result.Count > 0) return Ok(_mapper.Map<List<Card>, List<CardViewModel>>(result));
return NoContent();

// if single card object
if(result != null) return Ok(_mapper.Map<Card, CardViewModel>())
return NoContent();
}

}
  

Надеюсь, вы найдете это полезным.

Комментарии:

1. это полезно, когда вам нужно каждый раз возвращать определенные поля, но в моем требовании это динамично, например, я возвращаю объект employee, у которого есть 5 полей (Id, Name, DOB, адрес, Тема) но в запросе клиенту нужны только два поля (Name и DOB), в другом запросе ему нужны три поля (Subject, Id, Address) и так далее ….

2. Хорошо, понял, ты думал о ExpandoObject из System. Динамическая сборка? вы можете использовать его для создания динамического объекта (dynamic obj = new ExpandoObject(); obj.Prop1 = «значение»;… и так далее). проверьте learn.microsoft.com/fr-fr/dotnet/api /…

Ответ №3:

Я решаю проблему с помощью OData, это потрясающе. Вы можете перейти по ссылке, чтобы реализовать OData в вашем .net core api , загрузив свои веб-API с помощью OData и ASP.NET Ядро

Ответ №4:

Вы могли бы вернуть Dictionary<string, object> и добавить нужные поля в виде записей, подобных этой

 [HttpGet]
[Route("api/v1/cards")]
public IActionResult Cards(inputParameters,selector,filtering)
{
    var result = new Dictionary<string, object>();
    result["variable1"] = "value1";
    if (something == true)
        result["variable2"] = 7;
    return OK(result);
}
  

Комментарии:

1. Нужные пользователю поля находятся в selector , поэтому установка их вручную не поможет.

2. Что такое selector ?

3. Это то, что я спросил у OP. :/

4. @HansKilian поля, которые клиент хочет получить в ответ, например, я возвращаю объект employee, у которого есть 5 полей (Id, Name, DOB, адрес, Тема) но в запросе клиенту нужны только два поля (Name и DOB), в другом запросе ему нужны три поля (Subject, Id, Address) и так далее ..

5. Тогда вы делаете if (selector.Contains("variable2")) result["variable2"] = 7; .