Unity3d: Запись файла на Yandex диск на C#

от автора

К моему удивлению, на столь популярный сервис, как Яндекс диск, не нашлось примеров записи файла на диск на языке программирования C#. На PHP же ситуация обратная, примеров вдоволь, например: https://snipp.ru/php/disk-yandex

Я, как человек, который практически не изучал веб, потратил сутки, чтобы разобраться, что к чему. Надеюсь, эта статья поможет кому-нибудь сэкономить время.

Итак, приступим. Первое, что вам необходимо сделать, это зарегистрировать своё приложение: https://oauth.yandex.ru/ На этом этапе ничего сложного нет, просто важно дать доступ REST API к нашему диску.

После того, как вы зарегистрировались, вы получите код ClientID OAuth. Он то нас и интересует.

Я использовал только простейший способ получения отладочного токена:
Переходим по ссылке, не забывая заменить в ней идентификатор приложения на полученный OAuth.
https://oauth.yandex.ru/authorize?response_type=token&client_id=<идентификатор приложения (OAuth)>

Вам выдастся код — токен.

Теперь, чтобы записать файл на диск, необходимо выполнить 2 http запроса. GET для получения url, на который мы будем заливать наш файл и PUT для загрузки этого файла.
(Об этом можно прочесть в официальной документации).

Также, я захотел сделать вывод информации о диске, прежде чем загружать файл. Всё это выглядит следующим образом:

using UnityEngine; using System.Net; using System.Net.Http; public class BackUpOnYandex : MonoBehaviour {     [Header("Отладочный токен")]     public string token = "";     [Header("Путь к файлу на компьютере")]     public string path = "";     [Header("Путь к файлу на диске")]     public string path_disk = "";      [Button(nameof(SaveAsync))]     public bool buttonField;     public async System.Threading.Tasks.Task SaveAsync()     {         await testAsync();         await testAsync2();     }      public async System.Threading.Tasks.Task testAsync()     {//Информация о диске         HttpClient client = new HttpClient();          HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://cloud-api.yandex.net/v1/disk");          request.Headers.Add("Accept", "application/json");         request.Headers.Add("Authorization", $"OAuth {token}");          HttpResponseMessage response = await client.SendAsync(request);         response.EnsureSuccessStatusCode();         string responseBody = await response.Content.ReadAsStringAsync();         Debug.Log("Информация о диске");         Debug.Log(responseBody);      }     public async System.Threading.Tasks.Task testAsync2()     {//ссылка для загрузки файла         HttpClient client = new HttpClient();          HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://cloud-api.yandex.net/v1/disk/resources/upload?path=" + path_disk + "&overwrite=true");          request.Headers.Add("Accept", "application/json");         request.Headers.Add("Authorization", $"OAuth {token}");          HttpResponseMessage response = await client.SendAsync(request);         response.EnsureSuccessStatusCode();         string responseBody = await response.Content.ReadAsStringAsync();         Debug.Log("Пришедший JSON:");         Debug.Log(responseBody);         int indexOfSubstring = responseBody.IndexOf("https");         responseBody = responseBody.Substring(indexOfSubstring);         int indexOfSubstring2 = responseBody.IndexOf("\"");         responseBody = responseBody.Substring(0, indexOfSubstring2);         Debug.Log("Ссылка для загрузки файла:" + responseBody);         HTTP_PUT(responseBody, path);      }      // HTTP_PUT Function Метод загрузки файла на url     public void HTTP_PUT(string Url, string filePath)     {         Debug.Log("Загружаем файл POST запросом");         using (WebClient client = new WebClient())         {             client.UploadFile(Url, filePath);         }         Debug.Log("Загружено");     } }

В скрипте для удобства используется отображение кнопки в редакторе, найденное где-то на просторах интернета:

using UnityEngine;  #if UNITY_EDITOR using UnityEditor; #endif  #if UNITY_EDITOR [CustomPropertyDrawer(typeof(ButtonAttribute))] public class ButtonDrawer : PropertyDrawer {     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)     {         string methodName = (attribute as ButtonAttribute).MethodName;         Object target = property.serializedObject.targetObject;         System.Type type = target.GetType();         System.Reflection.MethodInfo method = type.GetMethod(methodName);         if (method == null)         {             GUI.Label(position, "Method could not be found. Is it public?");             return;         }         if (method.GetParameters().Length > 0)         {             GUI.Label(position, "Method cannot have parameters.");             return;         }         if (GUI.Button(position, method.Name))         {             method.Invoke(target, null);         }     } } #endif  public class ButtonAttribute : PropertyAttribute {     public string MethodName { get; }     public ButtonAttribute(string methodName)     {         MethodName = methodName;     } }

При написании этого кода мне очень помогло 2 ссылки:


ссылка на оригинал статьи https://habr.com/ru/post/710994/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *