Hallo zusammen,
Ich habe ein Problem mit meiner WebAPI, welche ich "modernisieren" möchte und finde den Fehler nicht.
Beim Aufruf der folgenden Methode wird bei CreatedAtAction ein Fehler im Swagger ausgegeben.
// POST /api/Project
[HttpPost]
public async Task<ActionResult<ProjectDto>> CreateProjectAsync([FromBody] CreateProjectDto projectDto)
{
var existingId = await repository.GetProjectByIdAsync(projectDto.Id);
if(existingId is null)
{
ProjectModel project = new()
{
Uid = projectDto.Uid
};
// Projekt wird dem InMemProjectRepository korrekt hinzugefügt
await repository.CreateProjectAsync(project);
// Hier, bei der CreatedAtAction tritt der Fehler auf
return CreatedAtAction(nameof(GetProjectByIdAsync), new { id = project.Id }, project.AsDto());
}
else if(existingId.Id == projectDto.Id)
{
return BadRequest();
}
return BadRequest();
}
// GET /api/Project/{id}
[HttpGet("{id}")]
public async Task<ActionResult<ProjectDto>> GetProjectByIdAsync(int id)
{
var project = await repository.GetProjectByIdAsync(id);
if (project is null)
{
return NotFound();
}
return project.AsDto();
}
Fehlermeldung:
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.InvokeNextResultFilterAsyncTFilter,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.<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 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)HEADERS
=======
Content-Type: application/json
:authority: localhost:5001
:method: POST
:path: /api/Project
😒cheme: https
Accept: text/plain
Accept-Encoding: gzip, deflate, br
Accept-Language: de-CH,de-DE;q=0.9,de;q=0.8,en-US;q=0.7,en;q=0.6
Cookie: ai_user=nITrk|2022-01-04T22:21:05.590Z,ai_session=TVQAp|1641372830052|1641372830052
Host: localhost:5001
Referer: https://localhost:5001/swagger/index.html
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
Origin: https://localhost:5001
Content-Length: 72
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty
Ich danke Euch für die Unterstützung.
Gruss Lhyn
Müsste im Header bei Accept nicht auch application/json stehen?
Dort ist aktuell text/plain eingetragen.
Ansonsten sieht es auf den ersten Blick korrekt aus.
Hast du auch die Default Route gesetzt bzw. wie sehen die Routing Einstellungen aus?
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
Hallo T-Virus,
Danke Dir für die schnelle Antwort.
Routing:
[ApiController]
[Route("api/[controller]")] // api/Project
Muss mich mal schlau machen, wie ich produces = application/json einstellen kann.
Habe ich auf die schnelle nicht herausgefunden...
Gruss Lhyn
Hallo,
Produces ist wie HttpGet und HttpPost ein Attribut mit einem entsprechenden Parameter.
[Produces("application/json")]
Grüße
Verwende immer Routes und keine Action-Links.
Und generier Deine Links mit Hilfe des LinkGenerator
Routes sind viel performanter (im Vergleich), viel einfacher zu pflegen und zu verlinken.
Hinzu kommt dass Routes die einzigen Definitionen sind, die früh beim App Start knallen - alle andere erst beim Call.
Dadurch immer schwer zu testen.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo zusammen,
Habe es nun mit [Produces("application/json")] getestet und Accept ist nun im Json-Format, danke dafür.
CreatedAtAction knallt aber leider noch immer.
Bin kurz davor es mit einem return Ok(project.AsDto()); zu basteln 😉
@Abt, kannst Du bitte genauer auf Deine Lösung für mein Beispiel eingehen?
Habe mir vorhin die Doku angeschaut und nach Umsetzungen gegoogelt, leider ohne Erfolg
Scheint als arbeiten noch nicht viele mit dem LinkGenerator für Routing
Gruss Lhyn
Weiß nicht nach was Du gegoogelt hast, aber dann wohl nicht richtig Google Suche nach "c# linkgenerator sample"
https://wildermuth.com/2018/10/15/LinkGenerator-in-ASP-NET-Core-2-2/
Den Link Generator gibs schon paar Jahre.
Ansonsten ASP Core Routing Basics
Routing in ASP.NET Core
Code:
Hier der ca. 5 Jahre alte Link von Marius
Generating Route URLs in ASP.NET Core MVC — Marius Schulz
Ansonsten sieht man eigentlich auch schon an den Parametern alleine, was man übergeben kann.
Sind ja nur eine Handvoll Möglichkeiten.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Danke Dir, dachte das muss doch etwas neues sein...
Werde ich mir anschauen und gegebenenfalls umsetzen.
Gruss Lhyn