【问题标题】:Peculiar problem with method naming in C# [duplicate]C#中方法命名的特殊问题[重复]
【发布时间】:2022-01-09 14:05:45
【问题描述】:

我在 ASP.NET Core 中遇到了一个特殊问题。我有一个创建后返回实体的方法。

        [HttpGet("{id}")]
        public async Task<IActionResult> GetItemAsync(int id)
        {
            var entity = await _unitOfWork.UserRepository.FindByIdAsync(id);
            if (entity == null)
                return NotFound();
            return Ok(entity);
        }

        [HttpPost]
        public async Task<IActionResult> CreateUser(UserNewDto userNewDto)
        {
            if (ModelState.IsValid)
            {
                var entity = new User()
                {
                    UserName = userNewDto.UserName,
                    FirstName = userNewDto.FirstName,
                    LastName = userNewDto.LastName,
                    Email = userNewDto.Email,
                    PhoneMobile = userNewDto.PhoneMobile,
                    Password = userNewDto.Password,
                };

                await _unitOfWork.UserRepository.AddAsync(entity);
                await _unitOfWork.Complete();
                return CreatedAtAction("GetItemAsync", new { entity.Id }, entity);
            }

            return new JsonResult("Something went wrong") { StatusCode = 500 };
        }        

CreateUser 方法应该在创建用户后重定向到GetItemAsync。相反,我收到一条错误消息,说明以下内容

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.<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__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   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)

如果我将方法名称从 GetItemAsync 更改为 GetItem,重定向将按预期工作。我做错了什么?

【问题讨论】:

    标签: c# asp.net .net asp.net-core asp.net-web-api


    【解决方案1】:

    这是 .net-core 3.0 中的一个问题。请看Async suffix removal from controller action names:

    在 ASP.NET Core 3.0 中,ASP.NET Core MVC 删除了 Async 后缀 控制器动作名称。路由和链路生成都受到影响 在这个新的默认设置下。

    此更改不会影响使用 [ActionName] 指定的名称 属性。可以使用以下命令禁用默认行为 Startup.ConfigureServices 中的代码:

    services.AddMvc(options =>
        options.SuppressAsyncSuffixInActionNames = false);
    

    所以你可以:

    1. [ActionName]装饰你的动作:
      [ActionName("GetItemAsync")]
      [HttpGet("{id}")]
      public async Task<IActionResult> GetItemAsync(int id)
      
    2. 或者在配置服务时设置SuppressAsyncSuffixInActionNames = false
      public void ConfigureServices(IServiceCollection services)
      {
          services.AddControllers(options =>
              options.SuppressAsyncSuffixInActionNames = false); 
      

    【讨论】:

      猜你喜欢
      • 2011-04-22
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 2013-05-09
      • 1970-01-01
      • 2020-12-18
      • 2015-08-10
      • 1970-01-01
      相关资源
      最近更新 更多