Search code examples
c#json.netasp.net-core-3.1

"Pass through" controller action (gets and returns JSON) in .NET Core 3.1


Someone's probably done this before but I can't seem to formulate the question properly to find results. I want to make AJAX calls from a view, but I can't directly call the external API from JavaScript because there's a key that I can't expose. My idea is to have another controller action that I call from the page that calls the actual external REST API I want to get data from and just passes it on as a JSON. I see lots of examples of getting a JSON through C# and deserializing it but not many where you get a JSON and then return it and consume it from the view. Any help appreciated.

public JsonResult GetStuff()
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri(URL);

            client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = client.GetAsync("Stuff/?Id=" + id).Result;

*code to take response and pass it on as a JSON that I can consume from Javascript 
        }

Solution

  • Here is what I recommend.

        [HttpGet("myapi/{id}");
        public async Task MyApi(int id) {
          // Replace these lines as needed to make your API call properly.
          using HttpClient client = new() {
            BaseAddress = REMOTE_SERVER_BASE
          }
          // Make sure to properly encode url parameters if needed
          using HttpResponseMessage response = await client.GetAsync($"myapi/{id}");
    
          this.HttpContext.Response.StatusCode = (int)response.StatusCode;
          foreach (KeyValuePair<string, IEnumerable<string>> header in response.Headers) {
            this.HttpContext.Response.Headers[header.Key] = new StringValues(header.Value.ToArray());
          }
    
          await response.Content.CopyToAsync(this.HttpContext.Response.Body);
        }
    

    This will copy all the common response fields such as status code, headers, and body content, over to your response.

    This code isn't tested so you might have to tweak it a bit but it should be enough to get you started.