К моему удивлению, на столь популярный сервис, как Яндекс диск, не нашлось примеров записи файла на диск на языке программирования 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 ссылки: