Search code examples
c#dotnetnukesystem.net

How do I resolve 302 Error when using HttpClient?


I've created a custom DNN module that uses HTTPClient to send information to an external API. My HttpClient method is as follows:

public static async Task<string> CreatePayerResponse()
    {
        var credentials = GetCredentials();
        var objEventLog = new EventLogController();
        var gatewaySettings = new GatewaySetting_ProPay();
        SignupResult_ProPay result = new SignupResult_ProPay();
        using (HttpClient client = new HttpClient(new LoggingHandler(new HttpClientHandler())))
        {
            HttpRequestMessage request = new HttpRequestMessage();
            HttpResponseMessage response = new HttpResponseMessage();
            response.EnsureSuccessStatusCode();
            client.BaseAddress = new Uri("https://xmltestapi.propay.com/ProPayAPI/signup");
            client.DefaultRequestHeaders.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            string responseBody;
            GatewaySetting_ProPay gatewaySetting = new GatewaySetting_ProPay();
            SignupRequest payerRequest = new SignupRequest();
            HttpContent content = new StringContent(payerRequest.ToString());
            try
            {
                request.Headers.Add("Authorization", credentials);
                request.Headers.Add("accept", "application/json");
                response = await client.PutAsync("https://xmltestapi.propay.com/ProPayAPI/signup", content);
                responseBody = await response.Content.ReadAsStringAsync();
                objEventLog.AddLog("Merchant Onboarding Request Sent", portalSettings, userId,
                    response.ToString(), EventLogController.EventLogType.ADMIN_ALERT);
                Console.WriteLine(responseBody);

            }
            catch (HttpRequestException ex)
            {
                result.Succeeded = false;
                result.Status = ex.Message;
                objEventLog.AddLog("Merchant Onboarding Error!", portalSettings, userId, response.ToString(),
                    EventLogController.EventLogType.ADMIN_ALERT);
                Console.WriteLine("\nException Caught!");
                Console.WriteLine("Message :{0} ", ex.Message);
            }

            return response.Content.ToString();
        }
    }
public static string GetCredentials()
    {
        GatewaySetting_ProPay gatewaySettings = new GatewaySetting_ProPay();
        var billerAccountId = "mycreds";
        var authToken = "mycreds";
        var encodedCredentials =
            Convert.ToBase64String(Encoding.Default.GetBytes(billerAccountId + ":" + authToken));
        var credentials = string.Format("Basic {0}", encodedCredentials);
        return credentials;
    } 

When I wire this method up to a click event, an HTTP 302 response is received and nothing is sent to the API. What modifications are needed to ensure proper transmission?

Update I still receive the following response:

Error code 302 was received from server response.

This is despite implementing the AllowAutoRedirect property and setting it to true. Here's the LoggingHandler class I've written:

public LoggingHandler(HttpMessageHandler innerHandler) : base(innerHandler)
    {

    }
    protected async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken, HttpClientHandler handler)
    {
        Console.WriteLine("Request:");
        Console.WriteLine(request.ToString());
        if (request.Content != null)
        {
            Console.WriteLine(await request.Content.ReadAsStringAsync());
        }
        Console.WriteLine();
        handler.AllowAutoRedirect = true;
        HttpResponseMessage response = await base.SendAsync(request, cancellationToken);


        Console.WriteLine("Response:");
        Console.WriteLine(response.ToString());
        if (response.Content != null)
        {
            Console.WriteLine(await response.Content.ReadAsStringAsync());
        }
        Console.WriteLine();

        return response;
    }

Is this the proper way to implement HttpClientHandler and associated properties?


Solution

  • After implementing trace logs for System.Net.Http and related namespaces, the logs stated that the connection was forcibly closed. After further research, it turns out the .NET Framework 4.5 is not compatible with more modern Transport Layer Security (TLS) versions. As such, the approach of calling the API from our DNN application had to be jettisoned because the source code we're extending targets .NET Framework version 4.5.