Я делаю веб-приложение (. NET Core 3.1), и в настоящее время у меня есть созданный API (с использованием контроллера API), который я хочу использовать в своем веб-приложении (и отображать его данные в представлении). API представляет собой несколько простых GET
запросов следующим образом (и прекрасно работает при доступе к нужным конечным точкам):
//GET: api/Fish
[HttpGet]
public IActionResult Get()
{
IEnumerable<Fish> fish = _dataRepository.GetAll();
return Ok(fish);
}
//GET: api/Fish/5
[HttpGet]
[Route("{id}")]
public IActionResult Get(long id)
{
Fish fish = _dataRepository.Get(id);
if (fish == null)
{
return NotFound("The fish could not be found");
}
return Ok(fish);
}
Теперь на моей домашней странице я хочу разрешить пользователю вводить конечную точку на моя форма, и я верну JSON из моего API. Это моя форма:
<form class="form-inline" asp-action="Index" asp-controller="Home">
<div class="form-group">
<label asp-for="Endpoint">https://url.com/api/</label>
<input type="text" class="form-control" placeholder="Try entering fish/4" asp-for="Endpoint"/>
<button type="submit" class="btn btn-primary">GET</button>
</div>
</form>
<div>
@Model.ReturnedJson
</div>
Вот модель представления:
public class GetDataViewModel
{
public string Endpoint { get; set; }
public string ReturnedJson { get; set; }
}
И контроллер моей домашней страницы, чтобы получить введенную конечную точку и получить JSON из API:
public async Task<IActionResult> Index(GetDataViewModel model)
{
var url = "https://localhost:44398/api/" + model.Endpoint;
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
var table = Newtonsoft.Json.JsonConvert.DeserializeObject(data);
model.ReturnedJson = data;
}
}
return View();
}
Что мне интересно, так это: HttpClient мой лучший выбор, чтобы справиться с этим? Я надеялся, что есть способ, которым я мог бы просто вызывать свои методы API, что-то вроде ApiController().Get
, но я не думаю, что это возможно (по крайней мере, в моем исследовании). Кроме того, возможно ли вернуть RAW (предпочтительно предварительно подтвержденный) JSON непосредственно на главной странице или мне нужно будет показать его в другом представлении? Я не уверен на 100%, что мой метод должен возвращать вместо return View()
, чтобы показать эти JSON данные.
Редактировать:
[HttpGet]
public IActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Index(GetDataViewModel model)
{
var request = new HttpRequestMessage(HttpMethod.Get, "https://localhost:44398/api/" + model.Endpoint);
var client = _clientFactory.CreateClient();
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync();
model.ReturnedJson = JsonConvert.SerializeObject(data, Formatting.Indented);
}
return View(model);
}
Это оба моих метода индекса в контроллере. Кажется, я получаю исключение Sustem.NullReferenceException при запуске веб-приложения. Я предполагаю, что это потому, что моя модель не передается при загрузке (первый метод Index), но если я добавлю ее туда, я получу ошибку, потому что тогда это то же объявление, что и для второго метода Index. Вот мое мнение:
@model TheFishAPI.Models.ViewModels.GetDataViewModel
@{
ViewData["Title"] = "Home Page";
}
<form class="form-inline" asp-action="Index" asp-controller="Home">
<div class="form-group">
<label asp-for="Endpoint">https://url/api/</label>
<input type="text" class="form-control" placeholder="Try entering fish/4" asp-for="Endpoint"/>
<button type="submit" class="btn btn-primary">GET</button>
</div>
</form>
<div>
@if (!string.IsNullOrEmpty(Model.ReturnedJson))
{
Html.Raw(Model.ReturnedJson);
}
</div>