Moja aplikacja pobierze listę wszystkich obrazów z określonego folderu i spróbuje przesłać je na serwer za pośrednictwem punktu końcowego interfejsu API

Ze względu na powyższe wymagania selektor obrazów nie jest odpowiedni

Poniżej znajduje się metoda w udostępnionym kodzie, do której jest przekazywana lista UIImages (na razie próbuję sprawić, by działała tylko z iOS, ale ten sam scenariusz zostanie ostatecznie zastosowany również do Androida)

Poniższe nie działa, ponieważ gdy przeglądam obraz na serwerze (AWS), jest w formacie kodu. Mówi również, że typ zawartości to application / json na serwerze, którego nie rozumiem, ponieważ ustawiam go na image / png

private async Task UploadImages(List<UIImage> images)
{            
    HttpClient client = new HttpClient();
    var contentType = new MediaTypeWithQualityHeaderValue("image/png");
    client.DefaultRequestHeaders.Accept.Add(contentType);
    client.DefaultRequestHeaders.Add("Id-Token", Application.Current.Properties["id_token"].ToString());

    foreach (var image in images)
    {
        try
        {                                        
            string baseUrl = $"https://********/dev/ferret-test/media/team1/user1/device1/test1.png";             
            client.BaseAddress = new Uri(baseUrl);

            //UploadModel uploadModel = new UploadModel
            //{
            //    image_file = image.AsPNG()
            //};

            byte[] bArray = null;
            Stream pst = image.AsPNG().AsStream();
            using (MemoryStream ms = new MemoryStream())
            {
                ms.Position = 0;
                pst.CopyTo(ms);
                bArray = ms.ToArray();
            }

            //string stringData = JsonConvert.SerializeObject(bArray);
            //var contentData = new StringContent(stringData,
            //System.Text.Encoding.UTF8, "image/png");

            //Byte[] myByteArray = new Byte[imageData.Length];
            //System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, myByteArray, 0, Convert.ToInt32(imageData.Length));                        

            var postRequest = new HttpRequestMessage(HttpMethod.Put, baseUrl)
            {
                Content = new ByteArrayContent(bArray)
            };

            var response = await client.SendAsync(postRequest);
            response.EnsureSuccessStatusCode();
            string stringJWT = response.Content.ReadAsStringAsync().Result;   
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    }
}       
0
Ryn9011 1 wrzesień 2020, 05:41

2 odpowiedzi

Najlepsza odpowiedź

Zarchiwizowałem przesyłanie wielu plików na serwer za pomocą następującego fragmentu, możesz spróbować ...

foreach (SQLiteAccess.Tables.Image image in images.OrderByDescending(x => x.Id)) //Here is the collection of all the file at once (Documents + Images)
{
      int documentId = UploadImageToServerAndroid(image).Result;
      // My other code implementation
      .
      .
      .
}

private async Task<int> UploadImageToServerAndroid(SQLiteAccess.Tables.Image image)
       {
           int documentId = 0;

           if (!Admins.ConnectedToNetwork()) return documentId;

           MyFile = FileSystem.Current.GetFileFromPathAsync(image.Path).Result;

           if (MyFile == null) return documentId;
         
           Stream stream = MyFile.OpenAsync(FileAccess.Read).Result;

           byte[] byteArray;
           byteArray = new byte[stream.Length];
           stream.Read(byteArray, 0, (int)stream.Length);
           
           if( !image.IsDocument )
           {
               try
               {
                   byteArray = DependencyService.Get<IImageUtilities>().CompressImage(byteArray); //Its custom code to compress the Image.
               }
               catch (Exception ex)
               {
                   UoW.Logs.LogMessage(new LogDTO { Message = ex.Message, Ex = ex });
               }
           }
           string url = "Your URL";
           using (HttpClient client = new HttpClient(new RetryMessageHandler(new HttpClientHandler())))
           {
               try
               {
                   client.DefaultRequestHeaders.Add(Properties.Resources.Authorization, Sessions.BearerToken);
                   client.DefaultRequestHeaders.Add("DocumentSummary", image.Comment);
                   client.DefaultRequestHeaders.Add("DocumentName", Path.GetFileName(image.Path));
                   MultipartFormDataContent multiPartContent = new MultipartFormDataContent();
                   ByteArrayContent byteContent = new ByteArrayContent(byteArray);
                   byteContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");
                   multiPartContent.Add(byteContent, "image", Path.GetFileName(image.Path));
                   HttpResponseMessage response = await client.PostAsync(url, multiPartContent);
                   if (response.IsSuccessStatusCode && response.Content != null)
                   {
                       string jsonString = response.Content.ReadAsStringAsync().Result;
                       DocumentDTO result = JsonConvert.DeserializeObject<DocumentDTO>(jsonString);
                       documentId = result.DocumentId;
                   }
               }
               catch(Exception ex)
               {
                   UoW.Logs.LogMessage( new LogDTO { Message = ex.Message, Ex = ex });
                   return documentId;
               }
           }
           return documentId;
       }

Jeśli documentid ma wartość 0 (jeśli coś poszło nie tak z jakiegoś powodu), zostanie oznaczony jako nieprzesłany i spróbuje przesłać go ponownie, gdy Internet będzie dostępny.

Jeśli potrzebujesz więcej pomocy, możesz zapytać ... :)

0
Blu 1 wrzesień 2020, 06:54

Możesz spróbować użyć MultipartFormDataContent i ustawić typ zawartości na application/octet-stream.

Możesz polecić dwa linki jeden i dwa.

0
Leo Zhu - MSFT 1 wrzesień 2020, 05:38