[英]Attribute Routing ASP Core 3.0
How do I specify routes to the following API endpoint using attribute routing?如何使用属性路由指定到以下 API 端点的路由?
The product object returned has a few attributes along with a Store and Manufacturer field that contain either null or a Store and Manufacturer object respectively.返回的产品对象具有一些属性以及分别包含 null 或 Store 和 Manufacturer 对象的 Store 和 Manufacturer 字段。
[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();
}
I would like to have a few readable routes to access and set the parameters appropriately.我想要一些可读的路由来访问和适当地设置参数。
[HttpGet ("")]
/api/Products
to return objects with Store and Manufacturer = null. /api/Products
返回 Store 和 Manufacturer = null 的对象。 This is desirable.("")
isn't needed when it is alone but necessary if I add other routes. ("")
单独使用时不需要,但如果添加其他路由则是必需的。 [Route("{stores=false}/{storeId=0})]
/api/Products/true
returns Product objects with Store filled and Manufacturer = null. /api/Products/true
返回 Store 已填充且 Manufacturer = null 的 Product 对象。 This is good./api/Products/true/1
filters on Store 1 which is also good./api/Products/true/1
过滤器也不错。 [Route("Stores/{storeId?})]
/api/Products/Stores/1
leaves stores = false, though filters on Store 1 but does not include the stores object. /api/Products/Stores/1
留下 stores = false,虽然过滤了 Store 1 但不包括 stores 对象。 "Stores" is not in the route data. /api/Products/Stores?storeId=1
doesn't work. /api/Products/Stores?storeId=1
不起作用。 Request.QueryString.Value = ?storeId=1 but that doeesn't bind to my storeId argument. I could continue describing my other experiments but suffice it to say, none gave me the results I'm looking for.我可以继续描述我的其他实验,但可以说,没有一个给我我正在寻找的结果。 I think I'm misunderstanding attribute routing but maybe it wasn't designed to do what I'm trying to do.
我想我误解了属性路由,但也许它不是为了做我想做的事情而设计的。
I guess what I'd like to see is either modifying a single url with a query string like,我想我想看到的是使用查询字符串修改单个网址,例如,
/api/Products?stores=true&manufacturerId=1
to get products with store info that are produced by manufacturer 1, or /api/Products?stores=true&manufacturerId=1
获取由制造商 1 生产的带有商店信息的产品,或/api/Products?storeId=1,stores=true,manufacturers=true
to get full details about the products in store 1 /api/Products?storeId=1,stores=true,manufacturers=true
获取有关商店 1 中产品的完整详细信息Alternatively, it would be ok to have或者,可以有
/api/Products/Stores/1
to get Products with store info for products in store 1 /api/Products/Stores/1
获取包含商店/api/Products/Stores/1
中产品的商店信息的产品/api/Products/Stores/Manufacturers/1
to get Projects with store and manufacturer info for those produced by manufacturer 1 /api/Products/Stores/Manufacturers/1
获取包含制造商 1 生产的项目的商店和制造商信息的项目Actually, I'm open to any URL schema that is readable.实际上,我对任何可读的 URL 模式都持开放态度。
Thanks!谢谢!
I would redesign the your API Controller a little bit.我会稍微重新设计一下你的 API 控制器。 Would be good if you give some meaningful names to your actions instead of
Get()
.如果您为您的操作指定一些有意义的名称而不是
Get()
那就太好了。
I also would create a service which will have the logic to provide the requested product and replace the _ctx
我还将创建一个服务,该服务将具有提供请求的产品并替换
_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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.