Собственно, в чем разница и что лучше использовать повсеместно и в каких случаях?
Вроде, результат будет в обоих случаях один и тот же...
Для приложения, которое будет пользоваться этим API разницы нет, а для контроллера это необходимо чтобы иметь возможность возвращать разные ответы (status code). Например:
public User GetUser(int id)
{
// ...
return user;
}
ничего плохого в таком коде нет, но если мы захотим отправить NotFound или BadRequest или другой код, нам компилятор не позволит, т.к. типы будут не сходиться, для этого и был придуман "общий" интерфейс IActionResult и его реализации: ActionResult<T>, OkResult, NotFoundResult и т.д. Это позволяет писать такой код:
public ActionResult<User> GetUser(int id)
{
if (/* тут может быть некая валидация */)
return BadRequest(); // возвращает BadRequestResult, т.е. код 400
if (/* ... */)
return NotFound(); // возвращает NotFoundResult, т.е. код 404
// ...
return user; // код 200, все ок
}
Фреймворк распознает эти типы и понимает как это правильно отправлять пользователю.
И ещё, лучше использовать вместо "чистого" интерфейса IActionResult его реализацию - ActionResult<T>. Это немного упрощает код, т.к. вместо return Ok(user); вы можете писать просто return user.
Подробнее можно почитать тут.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей