#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;
.