BPost地址验证C# REST调用不成功

Posted

技术标签:

【中文标题】BPost地址验证C# REST调用不成功【英文标题】:BPost address validation C# REST call no success 【发布时间】:2021-06-23 00:51:29 【问题描述】:

我正在尝试根据 Visual Studio C# 中的 BPost API 验证地址。 这是我第一次使用 Web 服务。

我找到了 Spatie 创建的 php 示例代码,并让它在我的计算机上以 WAMP 运行。 https://github.com/spatie/bpost-address-webservice 现在我想从 C# 中获得相同的功能。我没有转换成功。

这似乎是 PHP 代码的相关部分:

protected $client;

public function __construct()

    $this->client = new Client([
        'base_uri' => 'https://webservices-pub.bpost.be/ws/ExternalMailingAddressProofingCSREST_v1/',
    ]);


public function validateAddresses(ValidateAddressesRequest $validateAddressesRequest): ValidateAddressesResponse

    $response = $this->client->request('POST', 'address/validateAddresses', [
        'json' => $validateAddressesRequest->getBody(),
    ]);

    return new ValidateAddressesResponse(
        json_decode((string) $response->getBody(), true),
        $validateAddressesRequest->addresses()
    );


public function getBody(): array

    $addresses = array_map(function (Address $address, int $i) 
        return [
            '@id' => $i,
            'PostalAddress' => [
                'DeliveryPointLocation' => [
                    'StructuredDeliveryPointLocation' => [
                        'StreetName' => $address->streetName,
                        'StreetNumber' => $address->streetNumber,
                        'BoxNumber' => $address->boxNumber,
                    ],
                ],
                'PostalCodeMunicipality' => [
                    'StructuredPostalCodeMunicipality' => [
                        'PostalCode' => $address->postalCode,
                        'MunicipalityName' => $address->municipalityName,
                    ],
                ],
            ],
            'DeliveringCountryISOCode' => $address->country,
        ];
    , $this->addresses, array_keys(array_values($this->addresses)));

    return [
        'ValidateAddressesRequest' => [
            'AddressToValidateList' => [
                'AddressToValidate' => $addresses,
            ],
            'ValidateAddressOptions' => $this->options,
        ],
    ];

这是我迄今为止在 C# 中尝试过的:

static void Main(string[] args)
        
            Console.WriteLine("Start");

            var payload = "<@id>0</@id><PostalAddress><DeliveryPointLocation><StructuredDeliveryPointLocation><StreetName>Kaaistraat</StreetName><StreetNumber>1</StreetNumber><BoxNumber>1</BoxNumber>" + 
                "</StructuredDeliveryPointLocation></DeliveryPointLocation><PostalCodeMunicipality><StructuredPostalCodeMunicipality><PostalCode>8400</PostalCode>" +
                "<MunicipalityName>Oostende</MunicipalityName></StructuredPostalCodeMunicipality></PostalCodeMunicipality><DeliveringCountryISOCode>BE</DeliveringCountryISOCode>";

            HttpContent c = new StringContent(payload, Encoding.UTF8, "text/xml");

            var t = Task.Run(() => PostURI(c));
            t.Wait();

            Console.WriteLine("Feedback: " + t.Result);
            Console.WriteLine("End");
            Console.ReadLine();
        

        static async Task<string> PostURI(HttpContent c)
        
            var client = new HttpClient();
            client.BaseAddress = new Uri("https://webservices-pub.bpost.be/ws/ExternalMailingAddressProofingCSREST_v1/");

            HttpResponseMessage result = await client.PostAsync("address/validateAddresses", c);
            String response = result.IsSuccessStatusCode.ToString();
                if (result.IsSuccessStatusCode)
                
                    response = result.StatusCode.ToString();
                
            
            return response;
        

现在我得到一个“错误”作为 IsSuccessStatusCode。 排除故障以寻求解决方案的最佳下一步是什么?

【问题讨论】:

尝试在代码开头添加:ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;去年微软推出了一个安全更新,在服务器上禁用了 TLS 1.0 和 1.1,但没有改变客户端。因此,如果您的客户端上的默认 TLS 版本是 1.0 或 1.1,那么代码将不起作用。将默认值更改为 1.2 可能会解决问题。 谢谢jdweng。我添加了该行并运行,但它不会改变我的网络呼叫的响应。 我们需要确定 TLS 是否通过或问题出在哪里。最好的确定方法是使用像wireshark或fiddler这样的嗅探器。 TLS 发生在 HTTP 请求之前。因此,嗅探器将在成功请求时显示 TLS 部分,然后显示请求。如果没有请求 TLS 失败。检查 TLS 版本和证书块。证书块通过证书名称和加密模式列表从服务器发送到客户端。在您的情况下,TLS 失败 Net 版本不支持加密模式。您应该使用在操作系统中完成 TLS 的 Net 4.7.2 或更高版本。 【参考方案1】:

您可能需要对服务进行身份验证。如果您使用 Postman 发送此请求,您会收到带有 Access Denied 正文的 403。

【讨论】:

感谢您的提示,克里斯托弗。似乎 PHP 版本也没有进行身份验证,并且它在同一台计算机上工作。我会进一步调查确认。【参考方案2】:

当输入格式不正确时,Postman 确实指出了错误 403。 在 PHP 代码中引入 var_dump(json_encode($validateAddressesRequest->getBody())) 有助于找到正确的语法。

为了将来参考,这是现在可以工作的代码,由 Postman 生成。

        Console.WriteLine("Start");

        var client = new RestClient("https://webservices-pub.bpost.be/ws/ExternalMailingAddressProofingCSREST_v1/address/validateAddresses");
        String input = "\"ValidateAddressesRequest\":\"AddressToValidateList\":\"AddressToValidate\":[\"@id\":0,\"PostalAddress\":\"DeliveryPointLocation\":\"StructuredDeliveryPointLocation\":\"StreetName\":\"Kaaistrat\",\"StreetNumber\":\"1\",\"BoxNumber\":\"\",\"PostalCodeMunicipality\":\"StructuredPostalCodeMunicipality\":\"PostalCode\":\"8400\",\"MunicipalityName\":\"Oostende\",\"DeliveringCountryISOCode\":\"BELGIE\",\"@id\":1,\"PostalAddress\":\"DeliveryPointLocation\":\"StructuredDeliveryPointLocation\":\"StreetName\":\"Leanderhof\",\"StreetNumber\":\"\",\"BoxNumber\":\"\",\"PostalCodeMunicipality\":\"StructuredPostalCodeMunicipality\":\"PostalCode\":\"8550\",\"MunicipalityName\":\"Zwevegem\",\"DeliveringCountryISOCode\":\"BELGIE\"],\"ValidateAddressOptions\":[]";
        client.Timeout = -1;
        var request = new RestRequest(Method.POST);
        request.AddHeader("Content-Type", "application/json");
        request.AddHeader("Cookie", "AWSALB=2BqLxFZuWQumzA1q6UhL1Pza0w8Lq3FGCUfB2+aqjOYulz1gvQUfXgRLps4I3FEhyb/TRyZaAPxCaHWZ8ISg2/Mq5BRCZX+5NqnVll7EwiOkdSB9sIf9EfcWzvJI; AWSALBCORS=2BqLxFZuWQumzA1q6UhL1Pza0w8Lq3FGCUfB2+aqjOYulz1gvQUfXgRLps4I3FEhyb/TRyZaAPxCaHWZ8ISg2/Mq5BRCZX+5NqnVll7EwiOkdSB9sIf9EfcWzvJI; webservices-pub.bpost.be=2936274954.64288.0000");
        request.AddParameter("application/json", input, ParameterType.RequestBody);
        IRestResponse response = client.Execute(request);
        Console.WriteLine(response.Content);

        Console.Read();

【讨论】:

以上是关于BPost地址验证C# REST调用不成功的主要内容,如果未能解决你的问题,请参考以下文章

Springboot和Spring Security中认证成功后如何授权Rest API调用

如何查看app调用的rest接口

REST Web 服务身份验证令牌实现

jquery 不会在 $.ajax 上为 rails 标准 REST DELETE 答案调用成功方法

在Spring REST应用程序中成功验证后,为什么Principal为null?

C# 407 需要代理身份验证