Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Versions >= 8.2.0] EntitySet.EntityType.Action returns "Value cannot be null. (Parameter 'type')" #1177

Closed
CronKz opened this issue Feb 28, 2024 · 3 comments · Fixed by #1178
Labels
bug Something isn't working

Comments

@CronKz
Copy link
Contributor

CronKz commented Feb 28, 2024

Assemblies affected
Not working -> Versions >= 8.2.0.
Working -> Versions between 8.0.2 and 8.1.2 (Tested)

Describe the bug
Sending a POST request to an endpoint which maps to an EdmModel.EntitySet.EntityType.Action fails.

Reproduce steps

  1. Create a fresh Net 8 ASP .NET Web API Project using controllers
  2. Add <PackageReference Include="Microsoft.AspNetCore.OData" Version="8.2.4" /> to your project
  3. Add prop public int Id { get; set; } to WeatherForecast class to comply with OData key
  4. In Program.cs add this code
static IEdmModel GetEdmModel()
{
    var builder = new ODataConventionModelBuilder();
    var entitySet = builder.EntitySet<WeatherForecast>(nameof(WeatherForecast));
    entitySet.EntityType.Action(nameof(WeatherForecastController.Execute));
    return builder.GetEdmModel();
}
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers().AddOData(options => options.EnableQueryFeatures().AddRouteComponents(GetEdmModel()));
  1. In WeatherForecastController.cs replace with:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Query;
using Microsoft.AspNetCore.OData.Routing.Controllers;

namespace ODataActionFailing.Controllers;

[EnableQuery]
public class WeatherForecastController(ILogger<WeatherForecastController> logger) : ODataController
{
    [HttpPost]
    public WeatherForecast Execute(int key)
    {
        logger.LogInformation("We will only reach here with versions <= 8.1.2.\n" +
                               "Any Version >= 8.2.0 will not reach here.");
        return new WeatherForecast() { Id = key };
    }
}
  1. Run the api. Make a POST request to the "Execute" endpoint.
  2. Get an exception

Data Model
Please share your Data model, for example, your C# class.

public class WeatherForecast
{
    public int Id { get; set; }

    public DateOnly Date { get; set; }

    public int TemperatureC { get; set; }

    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);

    public string? Summary { get; set; }
}

Request/Response
Request: POST https://localhost:7034/WeatherForecast(123)/Execute
Response: 500 - Value cannot be null. (Parameter 'type')

Expected behavior
The POST request should reach to the controller and be handled there further.

Additional context
Exception Stack trace

System.ArgumentNullException: Value cannot be null. (Parameter 'type')
   at Microsoft.OData.Edm.EdmUtil.CheckArgumentNull[T](T value, String parameterName)
   at Microsoft.OData.Edm.EdmTypeSemantics.IsUntyped(IEdmType type)
   at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.CreateQueryOptionsOnExecuting(ActionExecutingContext actionExecutingContext)
   at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.OnActionExecuting(ActionExecutingContext actionExecutingContext)
   at Microsoft.AspNetCore.Mvc.Filters.ActionFilterAttribute.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
@CronKz CronKz added the bug Something isn't working label Feb 28, 2024
@julealgon
Copy link
Contributor

From the stacktrace, it looks like it's something inside [EnableQuery] attribute that is breaking it. I take it if you remove the attribute, the problem goes away?

Not suggesting that as a solution, just to pin down where the issue could be.

@CronKz
Copy link
Contributor Author

CronKz commented Feb 28, 2024

From the stacktrace, it looks like it's something inside [EnableQuery] attribute that is breaking it. I take it if you remove the attribute, the problem goes away?

Not suggesting that as a solution, just to pin down where the issue could be.

Yes indeed. Removing [EnableQuery] "fixes" the issue.
But as you mentioned, that's of course not a suitable solution.

@CronKz
Copy link
Contributor Author

CronKz commented Feb 28, 2024

It is caused by this call here:
8.1.2...8.2.0#diff-c2093e957abe0f043940441b15300600c6c65de2216e2e2409d82ee2666a22c2R139

Opend PR #1178 to fix the issue. Thank you @julealgon for pointing in the right direction!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
2 participants