我正在嘗試創建一個.net core 5 API。 我的控制器中有以下代碼。
[HttpGet]
public async Task<IActionResult> GetAll()
{
return Ok(await _repository.GetAllUsersAsync() )。
}
// GET api/<ReelTypes>/5
[Route("GetUserByIdAsync"/span>)]
[HttpGet("{id}", Name ="GetUserByIdAsync")]
public async Task<ActionResult<AppUser>> GetUserByIdAsync(Guid id)
{
var appUser = await _repository.GetUserByIdAsync(id)。
if(appUser == null)
{
returnNoContent()。
}
return Ok(appUser)。
}
[HttpPost]
[Route("CreateAsync")]
public async Task< IActionResult> CreateAsync([FromBody] AppUser model)
{
var checkExists = await _userManager.FindByNameAsync(model.UserName)。
if (checkExists != null)
{
return StatusCode(StatusCodes.Status409Conflict,
new _ResponseBody { Title = "Duplicate Record" ,
Body = "記錄已經存在" })。
}
AppUser user = new AppUser()
{
Email = model.Email。
SecurityStamp = Guid.NewGuid().ToString()。
UserName = model.UserName
};
var result = await _userManager.CreateAsync(user, model.PasswordHash)。
if (! result.Succeeded)
return StatusCode(StatusCodes.Status500InternalServerError,
new _ResponseBody { Title = "未創建",
Body = "Unable to create record" })。
return CreatedAtAction("GetUserByIdAsync", new { id = user.Id }, user) 。
我確實在努力遵循完整的規范,我知道當我用API創建一個物件時,回應需要包括新物件的URI和新物件。 為了做到這一點,我試圖使用CreatedAtAction函式。但無論我怎么做,我都會得到以下結果:
System.InvalidOperationException。沒有與提供的值相匹配的路由。
at Microsoft.AspNetCore.Mvc.CreatedAtActionResult.OnFormatting(ActionContext context)
在Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsyncCore(ActionContext context, ObjectResult result, Type objectType, Object value)
在Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsync(ActionContext context, ObjectResult result)
在Microsoft.AspNetCore.Mvc.ObjectResult.Executor.ExecuteResultAsync(ActionContext context)。
在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultAsync(IActionResult result)
在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,TFilterAsync]()
--- 堆疊跟蹤結束 從前一個位置 ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- 堆疊跟蹤結束 從前一個位置開始 ---
在Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
在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)
在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)
在Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
我曾嘗試使用GetName作為第一個引數,結果只是像現在這樣硬編碼。 所以我需要知道的是,我是個白癡嗎(明顯的答案是肯定的),還是這個函式有問題? 問題是我的GetById有一個Guid作為引數嗎? 是不是因為我在處理一個身份表的問題? 我是否必須使用版本管理?
我已經看了這里和其他地方關于這個問題的所有帖子,所以我沒有在第一時間發布這個帖子。 如果它是顯而易見的,我很抱歉,我只是錯過了它。
編輯:我已經嘗試對第一個引數使用nameof函式。 我還試著用[ActionName("GetUserByIdAsync")]來裝飾目標動作。
uj5u.com熱心網友回復:
替換
return CreatedAtAction("GetUserByIdAsync", new { id=user.Id }, user);
與
return GetUserByIdAsync(user.Id ) 。
uj5u.com熱心網友回復:
例外資訊準確地告訴你問題出在哪里:
沒有路線與提供的值相匹配。
如果你閱讀CreatedAtAction(string actionName, object value)的檔案:
actionName: 用于生成URL的動作的名稱。
那么,如果你閱讀了HttpGetAttribute.Name的檔案:
獲取路由名稱。路由名稱可用于使用特定的路由來生成一個鏈接,而不是依賴于基于給定的路由值集來選擇一個路由。
因此,問題在于你在用HttpGet裝飾你的控制器方法時沒有指定Name。換句話說,你所需要做的是:
// GET api/<ReelTypes> /5
[HttpGet("{id}", Name = "GetUserByIdAsync")/span>]
public async Task<ActionResult<AppUser>> GetUserByIdAsync(Guid id)
uj5u.com熱心網友回復:
我想明白了,我必須為Get動作指定我的引數的資料型別,把ActionName的裝飾加回去,然后再改成使用nameof。 所以我的代碼現在看起來像:
[HttpGet]
public async Task<IActionResult> GetAll()
{
return Ok(await _repository.GetAllUsersAsync() )。
}
// GET api/<ReelTypes>/5
[HttpGet("{id:Guid}", Name ="GetUserByIdAsync")/span>]
[ActionName("GetUserByIdAsync")]
public async Task<ActionResult<AppUser>> GetUserByIdAsync( [FromRoute] Guid id)
{
var appUser = await _repository.GetUserByIdAsync(id)。
if(appUser == null)
{
returnNoContent()。
}
return Ok(appUser)。
}
[HttpPost]
[Route("CreateAsync")]
public async Task< IActionResult> CreateAsync([FromBody] AppUser model)
{
var checkExists = await _userManager.FindByNameAsync(model.UserName)。
if (checkExists != null)
{
return StatusCode(StatusCodes.Status409Conflict,
new _ResponseBody { Title = "Duplicate Record" ,
Body = "記錄已經存在" })。
}
AppUser user = new AppUser()
{
Email = model.Email。
SecurityStamp = Guid.NewGuid().ToString()。
UserName = model.UserName
};
var result = await _userManager.CreateAsync(user, model.PasswordHash)。
if (! result.Succeeded)
return StatusCode(StatusCodes.Status500InternalServerError,
new _ResponseBody { Title = "未創建",
Body = "Unable to create record" })。
return CreatedAtAction(nameof(GetUserByIdAsync), new { id = user.Id }, user) 。
因此,這三個改動中的一個似乎已經解決了我的問題。 我懷疑是我現在指定了引數型別(Guid),但我也想知道裝飾的順序是否重要。 我第一次添加[ActionName]裝飾時,我把它放在了[HttpGet...]裝飾之上。
感謝所有試圖幫助我的人。 我希望這能幫助其他人解決這個問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/309489.html
標籤:
