Как стать автором
Обновить

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

Время на прочтение3 мин
Количество просмотров3.7K

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

Теги:
Хабы:
+2
Комментарии2

Публикации

Изменить настройки темы

Истории

Работа

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн