vknet / vk

Vkontakte API for .NET
https://vknet.github.io/vk/
MIT License
569 stars 222 forks source link

Проблемы с методом Api.Docs.Save и постом изображения на стену в группу #1020

Closed petr-ananev closed 4 years ago

petr-ananev commented 4 years ago

Пользовался гайдом https://github.com/vknet/vk/wiki/FAQ

Первая проблема что метод Api.Docs.Save падал с "Object reference not set to an instance of an object". Попробовал обойти эту проблему переопределив MediaAttachment и использовав Api.Photo.SaveMessagesPhoto для получения всех необходимых свойств MediaAttachment. В посте присутствует только текст сообщения.

  1. В чем может быть проблема отсутствия изображения в посте?
  2. Из за чего может падать Api.Docs.Save

        public class MediaAttachment : VkNet.Model.Attachments.MediaAttachment
    {
        protected override string Alias => "photo";
    }
    
    public class Service
    {
        public VkApi Auth()
        {
            VkApi api = new VkApi();
    
            api.Authorize(new ApiAuthParams {
                ApplicationId = AplicationParams.ApplicationId,
                Login = AplicationParams.Login,
                Password = AplicationParams.Password,
                Settings = AplicationParams.Settings
            });
    
            return api;
        }
        public async void Post(VkApi api, string message, string imagePath)
        {
            var uploadServer = api.Photo.GetMessagesUploadServer(api.UserId.Value);
    
            var response = await UploadFile(uploadServer.UploadUrl, "https://sun9- 64.userapi.com/c857336/v857336326/6434d/dUJywMrNS1c.jpg", "jpg");
    
            var attach = new List<MediaAttachment>();           
    
            var savedPhoto = api.Photo.SaveMessagesPhoto(response)[0];
    
            attach.Add(savedPhoto);
    
            var post = api.Wall.Post(new WallPostParams {
                OwnerId = AplicationParams.OwnerId,
                Message = message,
                Attachments = attach
            });
        }
        private async Task<string> UploadFile(string serverUrl, string file, string fileExtension)
        {
            // Получение массива байтов из файла
            var data = GetBytes(file);
    
            // Создание запроса на загрузку файла на сервер
            using (var client = new HttpClient())
            {
                var requestContent = new MultipartFormDataContent();
                var content = new ByteArrayContent(data);
                content.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
                requestContent.Add(content, "file", $"file.{fileExtension}");
    
                var response = client.PostAsync(serverUrl, requestContent).Result;
                return Encoding.Default.GetString(await response.Content.ReadAsByteArrayAsync());
            }
        }
        private byte[] GetBytes(string filePath)
        {
            return File.ReadAllBytes(filePath);
        }
petr-ananev commented 4 years ago

Похоже для поста на стену следовало использовать GetWallUploadServer + SaveWallPhoto. Но в итоге получаю ошибку "VkNet.Exception.InvalidHashException: 'Invalid hash'"

                public async void Post(VkApi api, string message, string imagePath)
        {       
            var uploadServer = api.Photo.GetWallUploadServer(AplicationParams.GroupId);

            var response = await UploadFile(uploadServer.UploadUrl, "https://sun9-64.userapi.com/c857336/v857336326/6434d/dUJywMrNS1c.jpg", "jpg");           

            var photo = api.Photo.SaveWallPhoto(response, (ulong?)api.UserId.Value)[0];

            var post = api.Wall.Post(new WallPostParams {
                OwnerId = AplicationParams.OwnerId,
                Message = message,
                Attachments = new List<MediaAttachment>() { photo }
            });

        }
        private async Task<string> UploadFile(string serverUrl, string file, string fileExtension)
        {
            // Получение массива байтов из файла
            var data = GetBytes(file);

            // Создание запроса на загрузку файла на сервер
            using (var client = new HttpClient())
            {
                var requestContent = new MultipartFormDataContent();
                var content = new ByteArrayContent(data);
                content.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
                requestContent.Add(content, "file", $"file.{fileExtension}");

                var response = client.PostAsync(serverUrl, requestContent).Result;
                return Encoding.Default.GetString(await response.Content.ReadAsByteArrayAsync());
            }
        }
        private byte[] GetBytes(string fileUrl)
        {
            using (var webClient = new WebClient())
            {
                return webClient.DownloadData(fileUrl);
            }
        }
petr-ananev commented 4 years ago

Заработало. Добавил GroupId var photo = api.Photo.SaveWallPhoto(response, (ulong?)api.UserId.Value, (ulong?)AplicationParams.GroupId)[0];