【问题标题】:ASP.NET Core 2.1 [FromQuery] not getting paramASP.NET Core 2.1 [FromQuery] 没有得到参数
【发布时间】:2020-02-05 22:31:23
【问题描述】:

我正在尝试使用 ASP.NET Core 2.1 从使用 [FromQuery] 的查询参数中获取我的 WebAPI 的参数。对于我的一生,我无法弄清楚我做错了什么。

具体动作如下所示:

[Route("api/[controller]/[action]")]
public class AuthController : Controller
{
    [HttpGet]
    [Authorize(Roles = "admin")]
    public async Task<IActionResult> GenerateCode([FromQuery]string email)
    {
        if (String.IsNullOrEmpty(email))
            return new BadRequestObjectResult(new ApiBadRequestResponse(new string[] { "Email is empty." }));

        var result = await _mediator.Send(new CreateAccessCode.Command
        {
            Email = email
        });

        if (result.Succeeded)
            return new OkObjectResult(new ApiOkResponse(result.Data));

        return new BadRequestObjectResult(new ApiBadRequestResponse(result.Errors));
    }
}

email 始终为 null,我在函数中放置了一个断点,因此我知道它会被调用。

我发送的请求是这样的:

{{url}}/api/auth/generatecode?email=test

如果我从头开始创建一个新项目,[FromQuery] 似乎可以工作,我不知道我在做什么不同。该操作被调用,但由于第一行而总是返回 BadResponse...

我的 startup.cs 函数如下所示:

services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddMvcOptions(options =>
            {
                options.Filters.Add(new ActionValidationFilter());
            })
            .AddFluentValidation()
            .AddJsonOptions(options =>
            {
                options.SerializerSettings.ContractResolver =
                new CamelCasePropertyNamesContractResolver();
            })
            .AddSessionStateTempDataProvider();

我完全迷路了。这是我在 WebAPI 中寻找查询参数的第一个操作。所有其他操作都在使用 FromBody 并且工作正常。

【问题讨论】:

  • 你用什么来提交数据到Web API?反应,角度,Jquery?请清楚地提及,以便我可以帮助您
  • 从你的方法中移除 [HttpPost] 属性。
  • 您不需要使用FormQuery,请删除[HttpPost]
  • 目前,只是使用邮递员发送请求。删除 HttpPost 或切换 HttpGet 不会改变行为。
  • 你试过不使用[FromQuery]吗?

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


【解决方案1】:

选项 1)
尝试将您的 [HttpGet] 属性更改为

[HttpGet("GenerateCode/{email}]

如果这样做,您需要从控制器的 Route 属性中删除 /[action],这样就可以了

[Route("api/[controller]")]

选项 2)
或者,在 Startup.cs 中将 app.UseMvc(); 更改为

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "api/{controller=Home}/{action=Index}/{id?}");
});

并从控制器属性中删除 [Route("api/[controller]/[action]")] 并确保您也没有 [ApiController] 属性

此解决方案将更改您整个项目的路由,因此您必须对所有其他 API 控制器执行相同操作

选项 3)
第三种解决方案是将[Route("api/[controller]/[action]")] 更改为

[Route("api/[controller]/[action]/{id?}")]

我已经测试了所有 3 个解决方案,它们都使用 URL {{url}}/api/ControllerName/ActionName?email=test

【讨论】:

  • 我尝试了这些解决方案中的每一个,但不幸的是,它们对我提供的 URL 不起作用。选项 2 似乎不是一个选项,因为我的项目纯粹是一个没有“HomeController”的 WebAPI。选项 3 在我的情况下似乎也不起作用,只是因为控制器中还有其他操作(为简洁起见,我省略了),并且适用于所有这些操作。选项 1 似乎不起作用。我仍然不清楚为什么 [FromQuery] 不起作用,尤其是当我创建一个新项目并且它在该项目中运行良好时。
  • @bryken 选项 2 只是一个模板,您不需要真正的 Home 控制器来工作。提醒:如果您使用选项 1,您仍然需要编辑路由属性以删除最后的 /[action]。为什么不能使用选项 3?最后的{id?} 是可选的(即{{url}}/api/ControllerName/ActionName 仍然可以使用选项3)
  • 我确实最终得到了这个工作。但是,我仍然不明白为什么 [FromQuery] 不起作用。我最终恢复了我所做的所有更改并再次重新启动,在这种情况下,我能够让 [FromQuery] 工作。我希望我第一次知道发生了什么,以提供更多见解,以防其他人遇到类似问题。感谢您的帮助。
【解决方案2】:

回答有点晚,但可能对其他人有帮助

选项 4

您可以在 [FromQuery] 属性中显式命名查询字符串参数名称

[HttpGet]
[Authorize(Roles = "admin")]
public async Task<IActionResult> GenerateCode([FromQuery(Name="email")] string email)
{

}

【讨论】:

    猜你喜欢
    • 2018-12-10
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    • 2019-02-20
    • 1970-01-01
    相关资源
    最近更新 更多