Маршрутизация атрибутов ASP Net Core и двойная косая черта

Как указано здесь, наличие двойной косой черты в URL-адресе допустимо.

У меня есть проект ASP Net Core, который использует маршрутизацию атрибутов, контроллер с именем GroupController для обработки операций с Groups и действие для PUTting RulePart группы, заданной его ImportId типа string.

[Route("/api/[controller]")]
public class GroupController : ControllerBase
{
    [HttpPut("{groupImportId?}/ruleParts")]
    public async Task<IActionResult> PutRuleParts(string groupImportId, [FromBody]List<RulePartDto> ruleParts)
    {
        return null; //actual code ommitted for brevity
    }
}

URL типа http://localhost/api/group/groupImportId/ruleParts соответствует ожидаемому.

Я ожидал, что null groupImportIds, то есть URL-адреса типа http://localhost/api/group//ruleParts вызовут то же действие, поскольку параметр маршрута groupImportId был помечен как необязательный. Однако при попытке вызвать этот URL-адрес я получаю ошибку 404, и действие не выполняется.

Есть ли возможность сопоставить пустой сегмент пути URL в ASP Net Core?


person Thaoden    schedule 09.05.2018    source источник
comment
Не используйте двойную косую черту. добавьте еще один маршрут, чтобы http://localhost/api/group/ruleParts также был действителен.   -  person Nkosi    schedule 09.05.2018
comment
@Nkosi Я не могу выбирать, что будет вызывать веб-клиент, поэтому я не могу контролировать, использует ли он двойную косую черту. Пожалуйста, не помечайте вопрос как дублированный, если это на самом деле не дублирование.   -  person Thaoden    schedule 09.05.2018
comment
Кроме того, предполагается, что в конце URL-адреса будут использоваться необязательные параметры. не будет работать при установке в середине. То, что вы ожидали, и то, что обрабатывает фреймворк, отличается.   -  person Nkosi    schedule 09.05.2018
comment
Затем удалите dup-flag, снова откройте, напишите это как ответ вместе с какой-нибудь ссылкой, чтобы я получил дополнительную информацию об ожидаемом размещении дополнительных параметров в AspNet Core WebApi, и я даже могу отметить ответ как принятый.   -  person Thaoden    schedule 09.05.2018
comment
Хотя любопытно. Почему для импорта должен быть необязательный идентификатор? каков этот сценарий?   -  person Nkosi    schedule 09.05.2018
comment
Возможно, я здесь слишком усложняю, но я хотел разобраться в случае, описанном выше: ошибка на стороне клиента, приводящая к вызову с пустым идентификатором groupImportId (т. Е. С двойной косой чертой).   -  person Thaoden    schedule 09.05.2018
comment
Ok. имеет смысл, но в этом случае правильным ответом будет 404. Так что я бы сказал, что вам даже не нужен второй маршрут. Удалите необязательный параметр, и, таким образом, любые недопустимые вызовы получат соответствующий ответ.   -  person Nkosi    schedule 09.05.2018
comment
В настоящее время я возвращаю 404 с дополнительной информацией. Но для этой дополнительной информации мне нужно действие, чтобы вручную заполнить ответ.   -  person Thaoden    schedule 09.05.2018
comment
Кстати, будет ли возврат 404 или 400 (неверный запрос) правильным (насколько это правильно с кодами состояния) кодом для возврата сюда? В конце концов, это неправильный запрос.   -  person Thaoden    schedule 09.05.2018
comment
404. Если бы вы смогли перехватить запрос и заявить, что идентификатор был нулевым, вы могли бы сказать 400.   -  person Nkosi    schedule 09.05.2018
comment
Звучит правильно. Спасибо.   -  person Thaoden    schedule 09.05.2018


Ответы (1)


Не используйте необязательный параметр в середине шаблона маршрута.

Необязательные параметры должны использоваться в конце URL-адреса. Маршруты не будут совпадать, если опущены необязательные параметры, встроенные в средние сегменты, так как это приведет к не найденным ошибкам.

Вместо этого маршрутизация атрибутов позволяет сопоставить несколько маршрутов одному действию.

[HttpPut("ruleParts")] // PUT api/group/ruleParts
[HttpPut("{groupImportId}/ruleParts")] //PUT api/group/123456/ruleParts
public async Task<IActionResult> PutRuleParts([FromBody]List<RulePartDto> ruleParts, string groupImportId = null) {
    //...
}

Аргумент groupImportId действия сделан необязательным, чтобы можно было опустить необязательный параметр в URL-адресе при запросе другого маршрута.

Ссылка Маршрутизация к действиям контроллера в ASP.NET Core

person Nkosi    schedule 09.05.2018
comment
Итак, в основном, структура Asp Net Core не может обрабатывать все допустимые URL-адреса? Спасибо за вклад, тогда мне придется поработать над своим API. - person Thaoden; 09.05.2018
comment
@Thaoden здесь проверяет теорию. верните параметр обратно как необязательный, как и изначально "{groupImportId?}/ruleParts", но используйте определение действия, которое я предоставил в своем ответе string groupImportId = null. Посмотрим, что будет теперь, когда вы cll /api/group//ruleParts - person Nkosi; 09.05.2018
comment
Было бы неплохо, если бы такое поведение было где-нибудь задокументировано. - person Thaoden; 09.05.2018