.net-coreblazorminimal-apisfast-endpoints

send object with GetFromJsonAsAsyncEnumerable


Working with .net8.0 Blazor Web App with MinimalAPI and FastEndpoints. Currently, to send an object to a get request that returns a list I'm using

        var req = new GetAgencyListRequest()
        {
            AgentLastName = _searchText,
            AgencyName = _searchText
        };

    using (var httpSvc = new HttpService(state))
    {
        var request = new HttpRequestMessage
            {
                Method = HttpMethod.Get,
                RequestUri = new Uri(httpSvc.BaseAddress + "agency/AgencyList"),
                Content = new StringContent(JsonSerializer.Serialize(req), Encoding.UTF8,
                    "application/json")
            };

        var response = await httpSvc.SendAsync(request);

        if (!response.IsSuccessStatusCode)
            throw new Exception("Could not get Agency list");

        using (var stream = response.Content.ReadAsStream())
        {
            var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
            _gridData = JsonSerializer.Deserialize<List<Agency>>(stream, options);
        }
    }

This works, but it seems like it could be simplified. I found GetFromJsonAsAsyncEnumerable, but can't find a way to send the request object. I could pass as parameters, but I have other more complex requests so I want to use this method.

var uri = new Uri("agency/AgencyList");
var resp = httpSvc.GetFromJsonAsAsyncEnumerable<Agency>(uri);

I can't find a way to send the object.

How do I send an object with this method?

Thank you


Solution

  • I came up with a few generic helper methods.

    public static class HttpHelper
    {
      public static async Task<List<T>> GetList<T>(StateContainer state, string route, object req)
      {
        using (var httpSvc = new HttpService(state))
        {
          var request = new HttpRequestMessage
          {
            Method = HttpMethod.Get,
            RequestUri = new Uri(httpSvc.BaseAddress + route),
            Content = new StringContent(JsonSerializer.Serialize(req), Encoding.UTF8,
                          "application/json")
          };
    
          var response = await httpSvc.SendAsync(request);
    
          if (!response.IsSuccessStatusCode)
            throw new Exception($"Could not get {typeof(T).Name} list");
    
          using (var stream = response.Content.ReadAsStream())
          {
            var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
            return JsonSerializer.Deserialize<List<T>>(stream, options).ToList();
          }
        }
      }
    
      public static async Task<List<T>> GetList<T>(StateContainer state, string route)
      {
        using (var httpSvc = new HttpService(state))
        {
          var response = await httpSvc.GetAsync(route);
    
          if (!response.IsSuccessStatusCode)
            throw new Exception($"Could not get {typeof(T).Name} list");
    
          using (var stream = response.Content.ReadAsStream())
          {
            var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
            return JsonSerializer.Deserialize<List<T>>(stream, options);
          }
        }
      }
    
      public static async Task<T> GetObject<T>(StateContainer state, string route, object req)
      {
        using (var httpSvc = new HttpService(state))
        {
          var request = new HttpRequestMessage
          {
            Method = HttpMethod.Get,
            RequestUri = new Uri(httpSvc.BaseAddress + route),
            Content = new StringContent(JsonSerializer.Serialize(req), Encoding.UTF8,
                          "application/json")
          };
    
          var response = await httpSvc.SendAsync(request);
    
          if (!response.IsSuccessStatusCode)
            throw new Exception($"Could not get {typeof(T).Name}");
    
          var responseStream = await response.Content.ReadAsStreamAsync();
          return JsonSerializer.Deserialize<T>(responseStream,
              new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
        }
      }
    
      public static async Task<T> GetObject<T>(StateContainer state, string route)
      {
        using (var httpSvc = new HttpService(state))
        {
          var response = await httpSvc.GetAsync(route);
    
          if (!response.IsSuccessStatusCode)
          {
            var errorMsg = await response.Content.ReadAsStringAsync();
            errorMsg = String.IsNullOrEmpty(errorMsg) ? $"Could not get {typeof(T).Name}"
                        : GetErrorMessage(errorMsg);
            throw new Exception(errorMsg);
          }
          var responseStream = await response.Content.ReadAsStreamAsync();
          return JsonSerializer.Deserialize<T>(responseStream,
              new JsonSerializerOptions { PropertyNameCaseInsensitive = true })!;
        }
      }
      private static string GetErrorMessage(string message)
      {
        string errorText = "called! - ";
    
        string msg = message;
        int index = msg.IndexOf("\r\n");
        msg = msg.Substring(0, index);
        msg = msg.Substring(msg.IndexOf(errorText) + errorText.Length);
        return msg;
      }
    }
    

    So now all that's needed to get an object or list is

    Agency _agency = await HttpHelper.GetObject<Agency>(state, $"agency/{AgencyID}");
    

    Just pass in the Type and the route..Done!