如何使用属性路由指定到以下API端点的路由?
返回的产品对象具有一些属性以及“商店”和“制造商”字段,分别包含null或“商店”和“制造商”对象。
[Route("api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase {
[HttpGet ("")]
public async Task<ActionResult<IEnumerable<Product>>> Get(
bool stores = false, int storeId = 0,
bool manufacturers = false, int manufacturerId = 0
) {
// Default - returns all Products
// stores = true will set Product.Store = to the store object
// storeId = 1 will filter Products to those in Store 1
// manufacturer = true will st Product.Manufacturer to a manufacturer object
// manufacturerId = 1 will filter Product to those produced by manufacturer 1
var products = await _ctx.GetProducts(
stores, storeId,
manufacturers, manufacturerId
);
return products.ToList();
}
我希望有一些可读的路径来访问和适当地设置参数。
[HttpGet ("")]
/api/Products
返回带有Store和Manufacturer = null的对象。这是理想的。("")
单独使用时并不需要,但是如果我添加其他路线,则是必需的。 [Route("{stores=false}/{storeId=0})]
/api/Products/true
返回带有商店已填充且制造商= null的产品对象。很好/api/Products/true/1
在商店1上的过滤器也不错。 [Route("Stores/{storeId?})]
/api/Products/Stores/1
使store = false,尽管在Store 1上进行了过滤,但不包括store对象。路径数据中没有“商店”。它在Request.Path中,但我不想去那里。/api/Products/Stores?storeId=1
不起作用。 Request.QueryString.Value =?storeId = 1,但不会绑定到我的storeId参数。我可以继续描述我的其他实验,但是可以说,没有一个给我想要的结果。我认为我对属性路由有误解,但也许并不是为了执行我想做的事情。
我想我想看到的是用查询字符串(如
)修改单个网址/api/Products?stores=true&manufacturerId=1
获取具有制造商1或/api/Products?storeId=1,stores=true,manufacturers=true
获取有关商店1中产品的完整详细信息或者,也可以
/api/Products/Stores/1
获取具有商店1中商品的商店信息的商品/api/Products/Stores/Manufacturers/1
获取包含制造商1生产的项目的商店和制造商信息的项目实际上,我愿意接受任何可读的URL架构。
谢谢!
答案 0 :(得分:0)
我会重新设计您的API控制器。如果您为自己的操作指定一些有意义的名称而不是Get()
。
我还将创建一个服务,该服务具有提供所请求产品并替换_ctx
// Default - returns all Products
[HttpGet ("")]
public async Task<ActionResult<IEnumerable<Product>>> GetAllProducts()
{
var products = await _ctx.GetAllProducts();
return products.ToList();
}
// stores = true will set Product.Store = to the store object
// storeId = 1 will filter Products to those in Store 1
[HttpGet ("Stores/{storeId?}")]
public async Task<ActionResult<IEnumerable<Product>>> GetProductsByStore(int? storeId)
{
if (storeId.HasValue)
{
// get products by store id
products = await _ctx.GetProductsByStoreId(storeId);
}
else
{
products = await _ctx.GetProductsByCurrentStore(); // just a suggestion I
have no idea what you mean by saying "..set Product.Store = to the store object"
}
return products.ToList();
}
// manufacturer = true will st Product.Manufacturer to a manufacturer object
// manufacturerId = 1 will filter Product to those produced by manufacturer 1
[HttpGet ("Manufacturers/{manufacturerId?}")]
public async Task<ActionResult<IEnumerable<Product>>> GetProductsByManufacturer(int? manufacturerId)
{
if (manufacturerId.HasValue)
{
products = await _ctx.GetProductsByManufacturerId(manufacturerId);
}
else
{
products = await _ctx.GetProductsByManufacturer();
}
return products.ToList();
}