2

Writing ASP.NET controllers, requires often to add multiple attributes to action methods, often repeatedly. It would be useful to create custom attributes that automatically combine other attributes to maintain a cleaner source code.

This post shows how to do it for properties, using class System.ComponentModel.PropertyDescriptor. Unfortunately there is not a System.ComponentModel.MethodDescriptor, so that example cannot translated to work on methods.

Does anyone know if this is possible and how?


Example:

    [<HttpGet("list-products")>]
    [<ProducesResponseType(typeof<Dto.Product list>, StatusCodes.Status200OK)>]
    [<ProducesResponseType(typeof<Dto.Exception>, StatusCodes.Status500InternalServerError)>]
    member this.ListProducts() = this.Http(Market.Product.all() |> AsyncSeq.map Dto.Of)

    [<HttpGet("find-product")>]
    [<ProducesResponseType(typeof<Dto.Product>, StatusCodes.Status200OK)>]
    [<ProducesResponseType(StatusCodes.Status404NotFound)>]
    [<ProducesResponseType(typeof<Dto.Exception>, StatusCodes.Status500InternalServerError)>]
    member this.FindProduct([<Required>] product: string) = this.Http(Market.Product.withName_ product |> Async.map (Option.map Dto.Of >> Option.toObj))

    [<HttpPost("start-feed")>]
    [<ProducesResponseType(StatusCodes.Status200OK)>]
    [<ProducesResponseType(typeof<Dto.Exception>, StatusCodes.Status500InternalServerError)>]
    member this.StartFeed([<Required>] contract: string) = this.ForwardToService(MineService, StartFeed contract)

    [<HttpPost("stop-feed")>]
    [<ProducesResponseType(StatusCodes.Status200OK)>]
    [<ProducesResponseType(typeof<Dto.Exception>, StatusCodes.Status500InternalServerError)>]
    member this.StopFeed([<Required>] contract: string) = this.ForwardToService(MineService, StopFeed contract)
   
    [<HttpPost("recalc-bars")>]
    [<ProducesResponseType(StatusCodes.Status200OK)>]
    [<ProducesResponseType(typeof<Dto.Exception>, StatusCodes.Status500InternalServerError)>]
    member this.RecalcBars([<Required>] product: string, fromUtc_: Nullable<DateTime>) = this.ForwardToService(MineService, RecalcBars (product, Option.ofNullable fromUtc_))

    [<HttpPost("reset-chart")>]
    [<ProducesResponseType(StatusCodes.Status200OK)>]
    [<ProducesResponseType(typeof<Dto.Exception>, StatusCodes.Status500InternalServerError)>]
    member this.ResetChart([<Required>] product: string) = this.ForwardToService(ChartService, ResetChart product)

Franco Tiveron
  • 2,364
  • 18
  • 34
  • 2
    Can you give an example of the attributes you would be combining? At least based on how I use attributes in Asp.Net, I can't foresee much benefit in combining attributes. How will you deal with attribute parameters? – gunr2171 Nov 03 '22 at 22:32
  • It isn't possible to define a custom attribute that combine several attributes. But in this specific case, [API conventions](https://learn.microsoft.com/en-us/aspnet/core/web-api/advanced/conventions) can do the job. – vernou Nov 03 '22 at 23:43

1 Answers1

0

As per @vernou suggestion, In this case I reached my objective using Api conventions

Franco Tiveron
  • 2,364
  • 18
  • 34