1

In ASP.NET Core-6 Web API, I am consuming a third party web service as shown here:

https://thirdpartyservice.com/api/Account/GetCustomerDetail/accountNumber

accountNumber is the parameter.

I am to validate and verify if the accountNumber exists.

So I have written this code.

appsettings.json:

  "MyEndpoints": {
    "custAccountDetailUrl": "https://thirdpartyservice.com/api/Account/GetCustomerDetail/"
  },

Kindly note that I am using HTTPClient.

Interface:

public interface IDataUtil
{;
    CustomerDetail GetCustomerDetail(string accountNumber);
}

Implementation:

public class DataUtil : IDataUtil
{
    private readonly IConfiguration _config;
    private readonly ILogger<DataUtil> _logger;
    private readonly HttpClient _myClient;
    public DataUtil
        (
        IConfiguration config,
        ILogger<DataUtil> logger, 
        HttpClient myClient
        )
    {
        _config = config;
        _logger = logger;
        _myClient = myClient;
    }

    public CustomerDetail GetCustomerDetail(string accountNumber)
    {
        var responseResults = new CustomerDetail();
        try
        {
            string custAccountNoUrl = _config.GetSection("MyEndpoints").GetValue<string>("custAccountDetailUrl") + accountNumber;
            _myClient.DefaultRequestHeaders.Accept.Clear();
            _myClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            HttpResponseMessage response = _myClient.GetAsync(custAccountNoUrl).Result;
            if (response.IsSuccessStatusCode)
            {
                var stringResult = response.Content.ReadAsStringAsync().Result;
                responseResults = JsonConvert.DeserializeObject<CustomerDetail>(stringResult);
            }
        }
        catch (Exception ex)
        {
            throw new Exception($"An Error occured " + ex.ToString());
        }
        return responseResults;
    }
}

Then I try to call it this way:

var accDetail = _dataAccess.GetCustomerDetail(model.AccountNumber);

Program.cs:

var builder = WebApplication.CreateBuilder(args);
ConfigurationManager configuration = builder.Configuration;
var environment = builder.Environment;
var swaggerDocOptions = new SwaggerDocOptions();

// Configure the HTTP request pipeline.
app.UseSwagger();
app.UseSwaggerUI();
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();

app.UseHsts();
app.UseCors(x => x
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader());

app.UseStaticFiles();

app.MapControllers();
string? port = Environment.GetEnvironmentVariable("PORT");
if (!string.IsNullOrWhiteSpace(port))
{
    app.Urls.Add("http://*:" + port);
}
app.Run();

The surprising thing is that it works on the local, but when I deployed it to the Server using IID, I got this error:

System.Exception: An Error occured System.InvalidOperationException: An invalid request URI was provided. Either the request URI must be an absolute URI or BaseAddress must be set.
   at System.Net.Http.HttpClient.PrepareRequestMessage(HttpRequestMessage request)
   at System.Net.Http.HttpClient.CheckRequestBeforeSend(HttpRequestMessage request)
   at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.GetAsync(String requestUri)
   at DDM.Application.Data.Concrete.DataUtil.GetCustomerDetail(String accountNumber) in C:\MyFolder\MyApplication\Data\Concrete\DataUtil.cs:line 71
   at DDM.Application.Data.Concrete.DataUtil.GetCustomerDetail(String accountNumber) in C:\MyFolder\MyApplication\Data\Concrete\DataUtil.cs:line 80

line 71:

HttpResponseMessage response = _myClient.GetAsync(custAccountNoUrl).Result;

line 80:

throw new Exception($"An Error occured " + ex.ToString());

How do I resolve this?

halfer
  • 19,824
  • 17
  • 99
  • 186
Ayobamilaye
  • 1,099
  • 1
  • 17
  • 46

1 Answers1

1

I ran into this issue as well. I found this question posted: Similar Stack Overflow Question : With this answer

Your HttpClient does not have a base URI set.

public CustomerDetail GetCustomerDetail(string accountNumber)
{
    var responseResults = new CustomerDetail();
    try
    { 
        // Get base uri : In your case
        string baseUri = "https://thirdpartyservice.com/api/"; //_config.GetSection("MyEndpoints").GetValue<string>("custAccountDetailUrl");

        string custAccountNoUrl = "Account/GetCustomerDetail/" + accountNumber; //_config.GetSection("MyEndpoints").GetValue<string>("custAccountDetailUrl") + accountNumber;

        // Set HttpClient base address
        _myClient.BaseAddress = new Uri(baseUri);

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

        // Use relative path for the GetAsync call
        HttpResponseMessage response = _myClient.GetAsync(custAccountNoUrl).Result;
        if (response.IsSuccessStatusCode)
        {
            var stringResult = response.Content.ReadAsStringAsync().Result;
            responseResults = JsonConvert.DeserializeObject<CustomerDetail>(stringResult);
        }
    }
    catch (Exception ex)
    {
        throw new Exception($"An Error occured " + ex.ToString());
    }
    return responseResults;
}
SpookyBooky
  • 129
  • 2
  • 9