简体   繁体   English

属性路由 ASP Core 3.0

[英]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.这是可取的。
    • The ("") 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.商店 1 上的/api/Products/true/1过滤器也不错。
    • But it is a stupid url (true? - products, stores, or manufacturers?)但这是一个愚蠢的网址(是真的吗? - 产品、商店或制造商?)
  • [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. “商店”不在路线数据中。 It is in the Request.Path but I don't want to go there.它在 Request.Path 中,但我不想去那里。
    • /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. Request.QueryString.Value = ?storeId=1 但这不会绑定到我的 storeId 参数。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM