首页 > 解决方案 > CreatedAtAction 方法返回“没有路由匹配提供的值。”

问题描述

我有一个 http post 方法,我为它的测试编写了下面的测试:

public async Task TestAdd_NewLicenseType()
{
    using(var context = new LicenseGenContext(ContextOptions))
    {
        var controller = new LicenseTypeController(context);
        var newLiceneType = new LicenseType()
        {
            LicenseTypeId = Guid.NewGuid(),
            LicenseTypeName = "TypeOne",
            LicenseTypeDescription = "License for StandAlone players"
        };

        var result = await controller.AddAsync(newLiceneType);

        Assert.IsAssignableFrom<CreatedAtActionResult>(result);
    }

}

Http post 写在控制器中,如下所示:

[HttpPost]
[Route("AddLicenseType")]
public async Task<ActionResult> AddAsync(LicenseType newLicenseType)
{
    
    if (!ModelState.IsValid)
    {
        return new Microsoft.AspNetCore.Mvc.BadRequestObjectResult(ModelState);
    }

    var result = await _context.LicenseTypes.AddAsync(newLicenseType);
    _context.SaveChanges();

    return CreatedAtAction("FindById", new { id = newLicenseType.LicenseTypeId }, newLicenseType);

}

我创建了一个 HttpGet 方法并将其命名为FindById,该方法在 post 方法中引用:

[HttpGet("{id}", Name ="FindById")]
//[ActionName("FindById")]
private async Task<ActionResult<LicenseType>> FindById(Guid id )
{
    var licenseType = await _context.LicenseTypes.FirstOrDefaultAsync(e => e.LicenseTypeId == id);

    if (licenseType == null)
    {
        return NotFound();
    }

    else
    {
        return licenseType;
    }
}

测试通过,当我使用正确的参数调用此 API 时,我可以在数据库中看到一个新条目。但是 Swagger UI 测试工具给了我以下错误

System.InvalidOperationException: No route matches the supplied values.
   at Microsoft.AspNetCore.Mvc.CreatedAtActionResult.OnFormatting(ActionContext context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsyncCore(ActionContext context, ObjectResult result, Type objectType, Object value)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsync(ActionContext context, ObjectResult result)
   at Microsoft.AspNetCore.Mvc.ObjectResult.ExecuteResultAsync(ActionContext context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultAsync(IActionResult result)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,TFilterAsync]()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

我在 StackOverflow 上阅读了一些类似的问题,但没有一个解决方案(从方法名称末尾删除 Async,在我的启动文件中添加SuppressAsyncSuffixInActionNames选项)对我有用。

有人可以告诉我当前的实施是否有问题吗?

标签: asp.net-core-webapitddxunitasp.net-core-5.0

解决方案


推荐阅读