• XSS.stack #1 – первый литературный журнал от юзеров форума

[C#] Отправка файлов в телеграм на базе .Net 4.0 - Без использования библиотек.

EmeliRouse

RAID-массив
Пользователь
Регистрация
28.06.2020
Сообщения
59
Реакции
138
Скрытый контент для зарегистрированных пользователей.
Создаём класс: MultipartFormBuilder.cs
C#:
namespace TelegramSenderEx
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;

    public class MultipartFormBuilder
    {

        private static readonly string MultipartContentType = "multipart/form-data; boundary=";
        private static readonly string FileHeaderTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n";
        private static readonly string FormDataTemplate = "\r\n--{0}\r\nContent-Disposition: form-data; name=\"{1}\";\r\n\r\n{2}";
        public string ContentType { get; private set; }
        private string Boundary { get; set; }

        Dictionary<string, FileInfo> FilesToSend { get; set; } = new Dictionary<string, FileInfo>();
        Dictionary<string, string> FieldsToSend { get; set; } = new Dictionary<string, string>();

        public MultipartFormBuilder()
        {
            Boundary = $"----------------------------{DateTime.Now.Ticks:x}";
            ContentType = $"{MultipartContentType}{Boundary}";
        }
        public void AddField(string key, string value) => FieldsToSend.Add(key, value);
        public void AddFile(FileInfo file)
        {
            string key = file.Extension.Substring(1);
            FilesToSend.Add(key, file);
        }
        public void AddFile(string key, FileInfo file) => FilesToSend.Add(key, file);
        public MemoryStream GetStream()
        {
            using var memStream = new MemoryStream();
            WriteFields(memStream);
            WriteStreams(memStream);
            WriteTrailer(memStream);
            memStream.Seek(0, SeekOrigin.Begin);
            return memStream;
        }
        private void WriteFields(Stream stream)
        {
            if (FieldsToSend.Count != 0)
            {
                foreach (KeyValuePair<string, string> fieldEntry in FieldsToSend)
                {
                    string content = string.Format(FormDataTemplate, Boundary, fieldEntry.Key, fieldEntry.Value);
                    using var fieldData = new MemoryStream(Encoding.UTF8.GetBytes(content));
                    fieldData.CopyTo(stream);
                }
            }
        }
        private void WriteStreams(Stream stream)
        {
            if (FilesToSend.Count != 0)
            {
                foreach (KeyValuePair<string, FileInfo> fileEntry in FilesToSend)
                {
                    WriteBoundary(stream);
                    string header = string.Format(FileHeaderTemplate, fileEntry.Key, fileEntry.Value.Name);
                    byte[] headerbytes = Encoding.UTF8.GetBytes(header);
                    stream.Write(headerbytes, 0, headerbytes.Length);
                    using FileStream fileData = File.OpenRead(fileEntry.Value.FullName);
                    fileData?.CopyTo(stream);
                }
            }
        }
        private void WriteBoundary(Stream stream)
        {
            byte[] boundarybytes = Encoding.UTF8.GetBytes($"\r\n--{Boundary}\r\n");
            stream.Write(boundarybytes, 0, boundarybytes.Length);
        }
        private void WriteTrailer(Stream stream)
        {
            byte[] trailer = Encoding.UTF8.GetBytes($"\r\n--{Boundary}--\r\n");
            stream.Write(trailer, 0, trailer.Length);
        }
    }
}

И ещё один класс помощник: WebClientExtensionMethods.cs
C#:
namespace TelegramSenderEx
{
    using System;
    using System.Net;

    public static class WebClientExtensionMethods
    {
        public static byte[] UploadMultipart(this WebClient client, string address, MultipartFormBuilder multipart)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            return client?.UploadData(address, stream.ToArray());
        }
        public static byte[] UploadMultipart(this WebClient client, Uri address, MultipartFormBuilder multipart)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            return client?.UploadData(address, stream.ToArray());
        }
        public static byte[] UploadMultipart(this WebClient client, string address, string method, MultipartFormBuilder multipart)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            return client?.UploadData(address, method, stream.ToArray());
        }
        public static byte[] UploadMultipart(this WebClient client, Uri address, string method, MultipartFormBuilder multipart)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            return client?.UploadData(address, method, stream.ToArray());
        }
        public static void UploadMultipartAsync(this WebClient client, Uri address, MultipartFormBuilder multipart)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            client?.UploadDataAsync(address, stream.ToArray());
        }
        public static void UploadMultipartAsync(this WebClient client, Uri address, string method, MultipartFormBuilder multipart)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            client?.UploadDataAsync(address, method, stream.ToArray());
        }
        public static void UploadMultipartAsync(this WebClient client, Uri address, string method, MultipartFormBuilder multipart, object userToken)
        {
            client.Headers.Add(HttpRequestHeader.ContentType, multipart.ContentType);
            using var stream = multipart.GetStream();
            client?.UploadDataAsync(address, method, stream.ToArray(), userToken);
        }
    }
}

И теперь самый главный класс с отправкой данных TGLog.cs
C#:
namespace TelegramSenderEx
{
    using System;
    using System.IO;
    using System.Net;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
    using System.Text;

    public static class TGLog
    {
        private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) => error.Equals(SslPolicyErrors.None);

        

        /// <summary>
        /// Метод для отправки архива в телеграм канал
        /// </summary>
        /// <param name="token">Токен канала</param>
        /// <param name="chatID">Чат ID пользователя</param>
        /// <param name="сaption">Заголовок сообщения</param>
        /// <param name="pathToFile">Полный путь до файла</param>
        private static void SendFile(string token, string chatID, string сaption, string pathToFile)
        {
              #region Установка протоколов безопасности для успешной отправки файлов
              // (SecurityProtocolType)(0xc0 | 0x300 | 0xc00)
              ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
              ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
                  | SecurityProtocolType.Ssl3
                  | (SecurityProtocolType)768 // Tls 11
                  | (SecurityProtocolType)3072; // Tls 12
             #endregion

             using var client = new WebClient { Proxy = null };
             var multipart = new MultipartFormBuilder();
             multipart.AddField("caption", сaption);
             multipart.AddField("chat_id", chatID);
             multipart.AddFile("document", new FileInfo(pathToFile)); // Добавление файла
             string UploadUrl = $"https://api.telegram.org/bot{token}/sendDocument?chat_id={chatID}"; // Тут ничего изменять не нужно.
             var url = new Uri(UploadUrl, UriKind.Absolute);
             var rawResponse = client.UploadMultipart(url, "POST", multipart); // Отправка файла через POST
             var response = Encoding.UTF8.GetString(rawResponse); // Для получения ответа...
         }
    }
}


 
Пожалуйста, обратите внимание, что пользователь заблокирован
Не проще так.
C#:
namespace System.Net
{
    using System.Security.Authentication;
    public static class SecurityProtocolTypeExtensions
    {
        public const SecurityProtocolType Tls12 = (SecurityProtocolType)SslProtocolsExtensions.Tls12;
        public const SecurityProtocolType Tls11 = (SecurityProtocolType)SslProtocolsExtensions.Tls11;
        public const SecurityProtocolType SystemDefault = 0;
    }
}

namespace System.Security.Authentication
{
    public static class SslProtocolsExtensions
    {
        public const SslProtocols Tls12 = (SslProtocols)0x00000C00;
        public const SslProtocols Tls11 = (SslProtocols)0x00000300;
    }
}
 private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) => error == SslPolicyErrors.None;
        public static void SSL()
        {
            // Установка сертификата для успешной загрузки файл(а)ов
            ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolTypeExtensions.Tls11 | SecurityProtocolTypeExtensions.Tls12;

        }

public static void POST(byte[] file, string filename, string contentType, string url)
        {
                SSL();
                WebClient webClient = new WebClient
                {
                    Proxy = null
                };
                string text = "------------------------" + DateTime.Now.Ticks.ToString("x");
                webClient.Headers.Add("Content-Type", "multipart/form-data; boundary=" + text);
                string @string = webClient.Encoding.GetString(file);
                string s = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"document\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n{3}\r\n--{0}--\r\n", new object[]
                {
                    text,
                    filename,
                    contentType,
                    @string
                });
                byte[] bytes = webClient.Encoding.GetBytes(s);
                webClient.UploadData(url, "POST", bytes); 
        }
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх