Result icon indicating copy to clipboard operation
Result copied to clipboard

Unable to cast object of type 'Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor' to type 'Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor'.

Open fp-jcorriveau opened this issue 2 years ago • 3 comments

Since the version 7.0.0, I get an exception

Unable to cast object of type 'Microsoft.AspNetCore.Mvc.Abstractions.ActionDescriptor' to type 'Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor'.

If I rollback to 4.0.2, everything seems fine. I can see the method has changed, I don't know if it's an issue with the controllers configuration

// fails when accessing controller.ControllerContext.ActionDescriptor

internal static ActionResult ToActionResult(this ControllerBase controller, Ardalis.Result.IResult result)
    {
      IDictionary<object, object> properties = controller.ControllerContext.ActionDescriptor.Properties;
      ResultStatusOptions resultStatusOptions = (properties.ContainsKey((object) "ResultStatusMap") ? properties[(object) "ResultStatusMap"] as ResultStatusMap : new ResultStatusMap().AddDefaultMap())[result.Status];
      int statusCode = (int) resultStatusOptions.GetStatusCode(controller.HttpContext.Request.Method);
      return result.Status == ResultStatus.Ok ? (!typeof (Ardalis.Result.Result).IsInstanceOfType((object) result) ? (ActionResult) controller.StatusCode(statusCode, result.GetValue()) : (ActionResult) controller.StatusCode(statusCode)) : (!(resultStatusOptions.ResponseType == (Type) null) ? (ActionResult) controller.StatusCode(statusCode, resultStatusOptions.GetResponseObject(controller, result)) : (ActionResult) controller.StatusCode(statusCode));
    }
   // The property is being cast here 
   // Microsoft.AspNetCore.Mvc.ControlleContext
    public new ControllerActionDescriptor ActionDescriptor
    {
        get { return (ControllerActionDescriptor)base.ActionDescriptor; }
        set { base.ActionDescriptor = value; }
    }

fp-jcorriveau avatar May 01 '23 17:05 fp-jcorriveau

I don't have the problem when using .WithResult<Result<T>> along with the attribute [TranslateResultToActionResult] instead of .WithActionResult and ToActionResult

// Fails 
public class MyEndpoint : EndpointBaseAsync.WithoutRequest.WithActionResult<MyResult>
{
    [HttpPost("/api/my-endpoint")]
    [ProducesResponseType(StatusCodes.Status200OK)]
   
    public override async Task<ActionResult<MyResult>> HandleAsync(CancellationToken cancellationToken = new CancellationToken())
    {
        return this.ToActionResult(await _service.DoSomething());
    }
}
// Is ok
[TranslateResultToActionResult]
public class MyEndpoint : EndpointBaseAsync.WithoutRequest.WithResult<Result<MyResult>>
{
    [HttpPost("/api/my-endpoint")]
    [ProducesResponseType(StatusCodes.Status200OK)]
   
    public override async Task<Result<MyResult>> HandleAsync(CancellationToken cancellationToken = new CancellationToken())
    {
        return await _service.DoSomething();
    }
}

fp-jcorriveau avatar May 01 '23 18:05 fp-jcorriveau

I am facing the same thing after upgrade - any clue ?

madhusameena avatar Feb 16 '24 10:02 madhusameena

I haven't had a chance to reproduce this. Is it still an issue in 9.x? I'm assuming so since I haven't changed anything but just want to confirm.

PR welcome if someone can identify the root cause.

ardalis avatar May 16 '24 18:05 ardalis