Interface using functional `Match` does not work
I'm using the OneOf library for discriminated unions
I have to use TypedResults in order to get OpenAPI to understand things.
For those unaware of the library
Match
works as public TResult Match<TResult>(Func<T0,TResult> f0, Func<T1,TResult> f1)
So it will either call the first lambda if CreateCustomerAsync
returns a CustomerResult
or the second lambda if it returns ValueNotFound
TypedResults.Created
and TypedResults.NotFound()
both extend the IResult
interface, so I hoped it would work but it seems like it doesn't
Cannot convert expression type 'Microsoft.AspNetCore.Http.IResult' to return type 'Microsoft.AspNetCore.Http.HttpResults.Results<Microsoft.AspNetCore.Http.HttpResults.Created<Support.Features.Customers.CreateCustomer.CreateCustomerResponse>,Microsoft.AspNetCore.Http.HttpResults.NotFound>'
31 Replies
The types in your return type and the type passed to
Match
aren't the sameI know but since both
Created
and NotFound
extend the same interface, shouldn't it work ? š¦I'm not sure about the details of
Match
. I've run into a similar problem with OneOf
But if Match
is returning an IResult
, that's what your method needs to returnI guess it can't cast it back to
Results<>
thenYou need to get
Match
to return a Results<Created<CustomerResult>, NotFound>>
Yeah, certainly not implicitly
Let me see how I did this with OneOfI casted it, and it simply went boom
I used this inside Match<> and it exploded inside the first lambda:
Cannot convert expression type 'Microsoft.AspNetCore.Http.HttpResults.Created<Support.Entities.Customer>' to return type 'Microsoft.AspNetCore.Http.HttpResults.Results<Microsoft.AspNetCore.Http.HttpResults.Created<Support.Features.Customers.CreateCustomer.CreateCustomerResponse>,Microsoft.AspNetCore.Http.HttpResults.NotFound>'
It can't convert
Created
into Results
This is an API endpoint right?
Yeah! using minimal api
Make the method return
IResult
I think that's what it should be returning anywayThis breaks OpenAPI
This is my endpoint's entire body
I have to use TypedResults in order to get OpenAPI to understand things.
that's why I said this hahahaAhhh right
This is the exact problem I had let me see which endpoint it was
Oh wait this is that endpoint
Here's the whole endpoint
I think using
Produces
is how I worked around itThat's not a bad idea tbh
Yeah, I think the only issue is that for whatever reason, that doesn't work with multiple codes
Although it should with multiple invocations
Produces<TNotFound>(404)
, Produces<TBadRequest>(400)
, etcThe only thing I don't like about
Produces
is that you can mess up the IResult
and you'll have no compiler to complainYeah this is weird
Cause you're right that the typed results implement
IResult
so they should work
I gotta go for now but I'm interested in this myself now so I'll get back to it later if you haven't solved it lolYeah the compiler in this case sees two conflicting possibilities for the type of
TResult
. You have to explicitly specify that TResult
is IResult
for this to work.That's the problem.. it doesn't work
not even this works it says that the cast is redundant
Does it not compile or does it just give you those redundancy warnings?
Not compile
Cannot convert expression type 'Microsoft.AspNetCore.Http.IResult' to return type 'Microsoft.AspNetCore.Http.HttpResults.Results<Microsoft.AspNetCore.Http.HttpResults.Created<Support.Features.Customers.CreateCustomer.CreateCustomerResponse>,Microsoft.AspNetCore.Http.HttpResults.NotFound>'
That's... odd
š¤
the problem is casting it back to the
Results
of the returnWait you're returning
Results<Created<CustomerResult>>
from the lambdathe
Match<IResult>
works
yesSo then yeah you quite obviously cannot convert
IResult
to that
(as already mentioned)I want to :((((((
It doesn't make sense
You can't implicitly convert an interface to a concrete type
how else should I go about doing it
turns out
i was returning the wrong type from the service:)
All you have to do is
type it there
it was just that I didn't return CustomerResult from the service, accidently:)
That's why it wasn't working:)
i'm dumb:)
Oh ok, my issue months ago was that I was trying to just cast what
Match
returns instead of calling Match<IResult>
nope just pass the return type inside match
as it's generic argument
and it's fine
although a bit verbose š¢