ASP.NET Core 2.1 [FromQuery] не получает параметр

Я пытаюсь получить параметр для моего WebAPI из параметра запроса, используя [FromQuery], используя ASP.NET Core 2.1. Для жизни меня я не могу понять, что я делаю неправильно.

Конкретное действие выглядит так:

[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 и работают нормально.


person bryken    schedule 16.07.2018    source источник
comment
Что вы используете для отправки данных в веб-API? Реагировать, Угловой, Jquery? Пожалуйста, четко укажите, чтобы я мог вам помочь   -  person    schedule 16.07.2018
comment
Удалите атрибут [HttpPost] из вашего метода.   -  person Umang    schedule 16.07.2018
comment
Вам не нужно использовать FormQuery и удалите [HttpPost]   -  person    schedule 16.07.2018
comment
На данный момент просто используйте почтальон для отправки запроса. Удаление HttpPost или переключение HttpGet не меняет поведение.   -  person bryken    schedule 16.07.2018
comment
Вы пробовали это без использования [FromQuery]?   -  person iSahilSharma    schedule 16.07.2018
comment
Я пробовал без [FromQuery], похоже, это тоже не работает.   -  person bryken    schedule 17.07.2018
comment
Вы отправляете строку с помощью json в метод?   -  person AliK    schedule 28.02.2019
comment
Здравствуйте, может быть, это не связано, но у меня была аналогичная проблема с ядром MVC .net (Entity Framework), где внутренние маршруты получения/ссылки и формы внезапно не работали... Я удалил контроллер и связанные представления, затем использовал Add New созданный элемент ... затем get-routes/links (по крайней мере) снова работали.   -  person Valter Ekholm    schedule 08.05.2021


Ответы (2)


Вариант 1)
Попробуйте изменить атрибут [HttpGet] на

[HttpGet("GenerateCode/{email}]

Вам нужно будет удалить /[action] из атрибута Route вашего контроллера, если вы сделаете это, так что это будет просто

[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.

person p3tch    schedule 16.07.2018
comment
Я попробовал каждое из этих решений, и, к сожалению, они не работают для меня с предоставленным URL-адресом. Вариант 2 не подходит, потому что мой проект представляет собой исключительно WebAPI без HomeController. Вариант 3 также, похоже, не работает в моем случае только потому, что в контроллере есть другие действия (которые я пропустил для краткости), и это будет применяться ко всем из них. Вариант 1 просто не работает. Мне до сих пор неясно, почему [FromQuery] не работает, особенно когда я создаю новый проект, и в нем он работает нормально. - person bryken; 17.07.2018
comment
@bryken Вариант 2 — это просто шаблон, для его работы вам не нужен настоящий домашний контроллер. Напоминание: если вы используете вариант 1, вам все равно нужно отредактировать атрибут маршрута, чтобы удалить /[action] с конца. Почему нельзя использовать вариант 3? Последний {id?} является необязательным (т. е. {{url}}/api/ControllerName/ActionName по-прежнему будет работать с вариантом 3). - person p3tch; 17.07.2018
comment
В итоге я заставил это работать. Однако я так и не понял, почему [FromQuery] не работает. В итоге я отменил все сделанные мной изменения и перезапустил снова, в этом случае я смог заставить [FromQuery] работать. Хотел бы я знать, что произошло в первый раз, чтобы дать больше информации на случай, если кто-то еще столкнется с подобной проблемой. Спасибо за помощь. - person bryken; 18.07.2018

Немного поздний ответ, но может быть полезен для других

Вариант 4

Вы можете явно указать имя параметра строки запроса в атрибуте [FromQuery].

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

}
person Jean-Sébastien Gervais    schedule 28.02.2019