title: Is HttpClient My Best Option to Consume an API in .NET Core MVC
body: <p>I am making a web app (.NET Core 3.1) and currently have an API created (using an API controller) that I want to consume in my web app (and display it's data on the View). The API is a few simple <code>GET</code> requests as following (and is working great when accessing the proper endpoints):</p>
  
  <pre><code>//GET: api/Fish
          [HttpGet]
          public IActionResult Get()
          {
              IEnumerable&lt;Fish&gt; 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);
          }
  </code></pre>
  
  <p>Now, on my homepage I want to allow the user to type in an endpoint on my form, and I will return the JSON from my API. This is my form:</p>
  
  <pre><code>&lt;form class="form-inline" asp-action="Index" asp-controller="Home"&gt;
      &lt;div class="form-group"&gt;
          &lt;label asp-for="Endpoint"&gt;https://url.com/api/&lt;/label&gt;
          &lt;input type="text" class="form-control" placeholder="Try entering fish/4" asp-for="Endpoint"/&gt;
          &lt;button type="submit" class="btn btn-primary"&gt;GET&lt;/button&gt;
      &lt;/div&gt;
  &lt;/form&gt;
  &lt;div&gt;
      @Model.ReturnedJson
  &lt;/div&gt;
  </code></pre>
  
  <p>Here is the view model:</p>
  
  <pre><code>public class GetDataViewModel
      {
          public string Endpoint { get; set; }
          public string ReturnedJson { get; set; }
      }
  </code></pre>
  
  <p>And my homepage controller to get the entered endpoint, and retrieve the JSON from the API:</p>
  
  <pre><code> public async Task&lt;IActionResult&gt; 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();
      }
  </code></pre>
  
  <p>What I'm wondering, is this:
  Is HttpClient my best bet to handle this? I was hoping there was a way I could just call my API methods, something like <code>ApiController().Get</code> but I don't think that is possible (at least in my research). Also, is it possible to return the RAW (preferably prettified) JSON directly on the homepage, or will I need to show it on a different view? I'm not 100% sure what my method should be returning in place of <code>return View()</code> to show that JSON data.  </p>
  
  <p>Edit:</p>
  
  <pre><code>[HttpGet]
          public IActionResult Index()
          {
              return View();
          }
  
          [HttpPost]
          [ValidateAntiForgeryToken]
          public async Task&lt;IActionResult&gt; 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);
          }
  </code></pre>
  
  <p>Those are both of my Index methods in the controller. I seem to be getting a Sustem.NullReferenceException when the web app starts up. I assume it's because my model isn't passed in on load (first Index method), but if I add it there, I get an error because it's then the same declaration as the second Index method. The following is my view:</p>
  
  <pre><code>@model TheFishAPI.Models.ViewModels.GetDataViewModel
  
  @{
      ViewData["Title"] = "Home Page";
  }
  
  &lt;form class="form-inline" asp-action="Index" asp-controller="Home"&gt;
      &lt;div class="form-group"&gt;
          &lt;label asp-for="Endpoint"&gt;https://url/api/&lt;/label&gt;
          &lt;input type="text" class="form-control" placeholder="Try entering fish/4" asp-for="Endpoint"/&gt;
          &lt;button type="submit" class="btn btn-primary"&gt;GET&lt;/button&gt;
      &lt;/div&gt;
  &lt;/form&gt;
  &lt;div&gt;
      @if (!string.IsNullOrEmpty(Model.ReturnedJson))
      {
          Html.Raw(Model.ReturnedJson);
      }
  &lt;/div&gt;
  </code></pre>