A
A
Alexander Abramov2015-10-02 10:16:51
C++ / C#
Alexander Abramov, 2015-10-02 10:16:51

How to send a POST request (HTTPS using TLS) (to a public procurement site)?

Greetings.
I was given the task of automatically uploading xml to the public procurement website. Unloading is carried out by sending a POST request to the web service of the state. procurement. The problem is that I have never done web programming, and in an attempt to figure it out, I get a non-working program :(
The documentation says:


The transfer of information is carried out via secure telecommunication channels at a specialized address ( https://zakupki.gov.ru/pgz/services/upload ) of the open part of the OOS using the HTTPS protocol. This uses the TLS cryptographic protocol (client authentication is not required).


An example of a POST request (variable values ​​are indicated in brackets):
POST /pgz/services/upload HTTP/1.1
Content-Type: multipart/form-data; boundary=---------------------7db10b11c0824
Host: zakupki.gov.ru
Content-Length: (content size)
Connection: Keep-Alive
Cache-Control: no-cache

-----------------------------7db10b11c0824
Content-Disposition: form-data; name="login"

(username)
-----------------------7db10b11c0824
Content-Disposition: form-data; name="password"

(password)
-----------------------7db10b11c0824
Content-Disposition: form-data; name="document"; filename="(filename)"
Content-Type: text/xml

(XML document)
-----------------------------7db10b11c0824

Well, based on all this, and the almighty Google, I dashed off a small console application for the test:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;

namespace MicrosoftWebRequestSample
{
    class Program
    {
        public static string boundary;

        static void Main(string[] args)
        {
            string boundary = "--AE337F6ACF9E45A4895CB7DB4372F700";
            StringBuilder sb = new StringBuilder();

            sb.Append(String.Format("{0}\r\nContent-Disposition: form-data; name=\"login\"\r\n\r\n{1}",
                            boundary,
                            "MyLogin"));

            sb.Append(String.Format("\r\n{0}\r\nContent-Disposition: form-data; name=\"password\"\r\n\r\n{1}",
                                    boundary,
                                    "MyPassword"));

            sb.Append(String.Format("\r\n{0}\r\nContent-Disposition: form-data; name=\"document\"; filename=\"{1}{2}\"\r\n\r\n{3}",
                                    boundary,
                                    "tenderPlanChange_ПГ2015_2015-09-29_1",
                                    ".xml",
                                    "Telo XML"));

            sb.Append(String.Format("\r\n{0}--\r\n", boundary));

            sendRequest(sb.ToString());
            Console.ReadKey();
        }

        static void sendRequest(string postData)
        {
            System.Net.HttpWebRequest webRequest;
            System.Net.HttpWebResponse httpWebResponse;
            System.IO.Stream stream;
            System.IO.StreamReader streamReader;
            System.Byte[] byteArray;
            System.Text.Encoding encodingUTF8;

            string statusDescription;
            string responseFromServer;
            Uri uri = new Uri("https://zakupki.gov.ru/pgz/services/upload");
            //Uri uri = new Uri("http://httpbin.org/post");

            try
            {              
                //1. Создать запрос.
                webRequest = (HttpWebRequest)WebRequest.Create(uri);
                webRequest.Method = "POST";
                webRequest.ProtocolVersion = HttpVersion.Version10;
                webRequest.KeepAlive = false;
                System.Net.Cache.RequestCachePolicy cashePol = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.NoCacheNoStore);
                webRequest.CachePolicy = cashePol;

                //2. Ввести данные к отправке и ковертировать их в массив байтов
                encodingUTF8 = System.Text.Encoding.UTF8;
                byteArray = encodingUTF8.GetBytes(postData);

                //3. Изменить свойства запроса: ContentType, ContentLength.
                webRequest.ContentType = "multipart/form-data; boundary=" + Program.boundary;
                //webRequest.ContentType = "text/xml";
                webRequest.ContentLength = byteArray.Length;

                Console.WriteLine("Request: \n {0}", postData);
                Console.ReadKey();

                //4. Если требуется авторизация, то указать учетные данные.
                //credentialCache = System.Net.CredentialCache.DefaultCredentials;

                ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback((s, ce, ch, ssl) => true);

                //5. Получить поток с данными.
                stream = webRequest.GetRequestStream();

                //6. Записать поток данных.
                stream.Write(byteArray, 0, byteArray.Length);

                //7. Закрыть поток.
                stream.Close();

                //8. Получить ответ.
                httpWebResponse = (System.Net.HttpWebResponse)webRequest.GetResponse();

                //9. Отобразить статус.
                statusDescription = httpWebResponse.StatusDescription;
                Console.WriteLine("{0}", statusDescription);

                //10. Получить поток с данными.
                stream = httpWebResponse.GetResponseStream();

                //11. Открыть поток с помощью StreamReader.
                streamReader = new System.IO.StreamReader(stream);

                //12. Прочитать содержимое.
                responseFromServer = streamReader.ReadToEnd();

                //13. Вывести содержимое в инфолог.
                Console.WriteLine("{0}", responseFromServer);

                //14. Закрыть все.
                streamReader.Close();
                stream.Close();
                httpWebResponse.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Ошибка");
                Console.WriteLine(ex.Message);
            }
        }
    }
}


But, I keep getting an error:
The request was aborted: Failed to create SSL/TLS secure channel.


Help me please :)

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alexander Abramov, 2015-10-07
@DarkSpirit22

I solved the problem, it was necessary to install the root certificate of the CA of the Treasury and CryptoPRO.

L
littleguga, 2015-10-02
@littleguga

Maybe these links will help

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question