Установите URI-адрес местоположения, указывающий на другой контроллер

#c# #asp.net-core-webapi

Вопрос:

У меня есть контроллер с действием, и я хочу установить LocationUri , чтобы он указывал на другой контроллер. Например, у меня есть:

 [Route("auth")]
[ApiController]
public class AuthorisationController
{
        [Route("{id}")]
        public IActionResult Put([FromRoute]string id, [FromBody]FooBar request)
        {
            return new CreatedResult("locationUri", SanitiseResponse(request));
        }
}

 

Я хочу LocationUri , чтобы он указывал на этот контроллер

 [Route("transaction")]
[ApiController]
public class TransactionController
{
    [Route("{id}")]
    public IActionResult Get([FromRoute] string id)
    {
        return new OkResult();
    }
}
 

Есть идеи, как мне это сделать? Я строил его сам, используя _httpContextAccessor , но задавался вопросом, есть ли лучший способ?

Ответ №1:

Именно здесь ControllerBase может помочь вывод из, поскольку он предоставляет вспомогательный элемент, который упрощает то, чего вы пытаетесь достичь

 [Route("auth")]
[ApiController]
public class AuthorisationController : ControllerBase {
    [Route("{id}")]
    public IActionResult Put([FromRoute]string id, [FromBody]FooBar request) {
        return CreatedAtAction("Get", "Transaction", { id = ??? }, SanitiseResponse(request));
    }
}
 

База эталонного контроллера.Метод CreatedAtAction

Вы все еще можете сделать это самостоятельно, используя CreatedAtActionResult

 [Route("auth")]
[ApiController]
public class AuthorisationController {
    [Route("{id}")]
    public IActionResult Put([FromRoute]string id, [FromBody]FooBar request) {
        return new CreatedAtActionResult("Get", "Transaction", { id = ??? }, SanitiseResponse(request));
    }
}
 

это в основном то, что обертывает вспомогательный метод.

Обратите ??? внимание на примеры, в которых вы бы указали id значение маршрута, которое в данном случае является частью сгенерированного URI

Чтобы избежать жесткого кодирования действия и контроллера, вы можете сделать следующее, но я нахожу это довольно подробным.

 //...

string actionName = nameof(TransactionController.Get);
string controllerName = nameof(TransactionController).TrimEnd("Controller");

return CreatedAtAction(actionName, controllerName, { id = ??? }, SanitiseResponse(request));

//...
 

Если имя контроллера или имя действия изменено, это позволит среде IDE автоматически вносить изменения или отображать синтаксическую ошибку, предупреждая вас об изменении.

Комментарии:

1. Спасибо, но я получаю сообщение об ошибке «Маршрут не соответствует заданным значениям». Есть какие-нибудь идеи, что могло бы вызвать это?

2. @DrSchizo проверьте обновленный ответ. Обратите внимание, что этот ответ основан конкретно на деталях, которые вы указали в вопросе. также, что такое полное сообщение об ошибке?

3. Я использовал nameof(TransactionController) , должно быть Transaction , как в твоем примере.

4. @DrSchizo Да, я понял, что он также использует полное название класса, поэтому я внес правку. Пытался избежать использования жестко закодированных строк, чтобы упростить рефакторинг. Это выполнимо, но потребуется больше кода, чтобы удалить «Контроллер» из имени.