Рабочий код C #, преобразованный в Powershell, приводит к SocketException - PullRequest
1 голос
/ 13 апреля 2019

У меня есть следующее консольное приложение C #, которое успешно вызывает конечную точку HTTP Post:

class Program
{
    static void Main(string[] args)
    {
        HttpClient httpClient = new HttpClient();
        httpClient.BaseAddress = new Uri("https://DomainOne.azure-api.net");
        httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "8b17badbbfe44e9e933453a8b4d8fc85");

        StringContent stringContent = new StringContent("\"hi\"", System.Text.Encoding.UTF8, "application/json");            
        Task<HttpResponseMessage> task = httpClient.PostAsync("integration/api/Result/CompanyOne", stringContent);
        HttpResponseMessage response = task.Result;

        var content = response.Content.ReadAsStringAsync().Result;
    }
}

Это эквивалентный скрипт Powershell, который я пытаюсь использовать:

$httpClient = New-Object 'System.Net.Http.HttpClient'
$httpClient.BaseAddress = New-Object 'System.Uri'('https://DomainOne.azure-api.net')
$httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "8b17badbbfe44e9e933453a8b4d8fc85");

$stringContent = New-Object 'System.Net.Http.StringContent'('"hi"', [System.Text.Encoding]::UTF8, 'application/json')
$task = $httpClient.PostAsync('integration/api/Result/CompanyOne', $stringContent)
$response = $task.Result

$content = $response.Content.ReadAsStringAsync().Result

Однако объект $task содержит следующее:

System.AggregateException: One or more errors occurred. 
---> System.Net.Http.HttpRequestException: An error occurred while sending the request. 
---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. 
---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. 
---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)
at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)
at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)
--- End of inner exception stack trace ---

Конечная точка размещается в нашей среде dev Azure за API-интерфейсом, а метод / контроллер действия выглядит следующим образом:

[ApiController]
[Route("api/[controller]")]
public class ResultController : ControllerBase
{                           
    [Route("{providerName}")]
    [HttpPost]
    public Task<bool> ReceiveMessage(HL7Message message)
    {
        return Task.FromResult(true);
    }
}

Вот настройки протокола в Azure API Management: Protocols

Почему я получаю SocketException в Powershell, а не в C #, и как мне заставить его работать в Powershell?

1 Ответ

1 голос
/ 13 апреля 2019

Основываясь на полезном комментарии Рика Рейни , вы можете форсировать версию TLS, добавив строку кода ниже перед вызовом HTTP:

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12

Я считаю, что это ограничениеиспользуемой версии .NET.Любая версия ниже .NET 4.6 будет по умолчанию использовать версию TLS, отличную от 1.2.

...