none
Bild aus URL in Datenbank speichern RRS feed

  • Frage

  • Hallo,

    ich möchte gern ein Bild von einer URL in der Datenbank (Feld = varbinary(max)) speichern.

    Leider finde ich nur Anleitungen mit dem WebClient und der ist wohl veraltet. Wie bekomme ich das mit dem aktuellen Framework umgesetzt?

    LG


    .::datekk::.

    Freitag, 20. Dezember 2019 18:23

Antworten

  • Ah ok.. Danke für den Converter Link.

    Ich habe es nun doch mit dem WebClienten umgesetzt, weil es hiermit doch sehr einfach geht. 

    Ich habe eine neue Methode erstellt: LoadAsStream

            public static byte[] LoadAsStream (string url)
            {
    
                byte[] buffer;
                using (WebClient client = new WebClient())
                {
                    
                    buffer = client.DownloadData(url);
    
                }
    
                return buffer;
    
    
    
            }

    Im Programm selbst habe ich dann einfach folgendes angewendet:

    Bilder bilder = new Bilder();
    
    Bilder.Bild = LoadAsStream(url);
    
    db.Tabelle.Add(tabelle);
    db.SaveChanges();
    


    .::datekk::.

    • Als Antwort markiert datekk2 Dienstag, 7. Januar 2020 10:37
    Dienstag, 31. Dezember 2019 12:14

Alle Antworten

  • Hi,
    das aktuelle .NET Core unterstützt WebClient (seit 2.2). Wenn Du es aber ohne WebClient machen willst, dann nutze HttpClient, z.B. so mit VB.NET (getestet in Core 3.1):

      Public Async Function DownloadFile(url As String) As Task(Of Byte())
        Using client As New HttpClient()
          Using result = Await client.GetAsync(url)
            If result.IsSuccessStatusCode Then Return Await result.Content.ReadAsByteArrayAsync
          End Using
        End Using
        Return Nothing
      End Function

    Inclusive Speichern könnten die Methoden so aussehen:

      Public Async Sub Execute(rootPath As String, filename As String)
        Dim buf = Await DownloadFile($"{rootPath}/{filename}")
        If buf IsNot Nothing Then
          Using cn As New SqlConnection(Settings.CnSQL)
            cn.Open()
            Using cmd As New SqlCommand("INSERT INTO Pictures(image) VALUES(@Img)", cn)
              cmd.Parameters.AddWithValue("@img", buf)
              cmd.ExecuteNonQuery()
            End Using
          End Using
        End If
      End Sub
    
      Public Async Function DownloadFile(url As String) As Task(Of Byte())
        Using client As New HttpClient()
          Using result = Await client.GetAsync(url)
            If result.IsSuccessStatusCode Then Return Await result.Content.ReadAsByteArrayAsync
          End Using
        End Using
        Return Nothing
      End Function


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks



    Samstag, 21. Dezember 2019 07:21
  • Hallo zusammen,

    nur als Ergänzung: Die HttpClient Klasse sollte pro Anwendung nur einmal instanziert werden, nicht pro Request, Anforderung, Aufruf, ...

    Siehe dazu:

      MSDN - HttpClient Klasse (Hinweise, ganz unten)

      You're using HttpClient wrong and it is destabilizing your software


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Samstag, 21. Dezember 2019 15:10
    Moderator
  • Hi,
    der Einwand zur einmaligen Instanziierung ist natürlich berechtigt. Dann sollte der Code so aussehen:

    Imports System.Data.SqlClient
    Imports System.Net.Http
    
    Public Class Demo01
    Public Async Sub Execute(rootPath As String, filename As String) Dim buf = Await DownloadFile($"{rootPath}/{filename}") If buf IsNot Nothing Then Using cn As New SqlConnection(Settings.CnSQL) cn.Open() Using cmd As New SqlCommand("INSERT INTO Pictures(image) VALUES(@Img)", cn) cmd.Parameters.AddWithValue("@img", buf) cmd.ExecuteNonQuery() End Using End Using End If End Sub Public Async Function DownloadFile(url As String) As Task(Of Byte()) Using result = Await Client.GetAsync(url) If result.IsSuccessStatusCode Then Return Await result.Content.ReadAsByteArrayAsync End Using Return Nothing End Function Private Shared _client As HttpClient = Nothing Public Shared ReadOnly Property Client As HttpClient Get If _client Is Nothing Then _client = New HttpClient Return _client End Get End Property End Class


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    Sonntag, 22. Dezember 2019 12:13
  • Hi... Sorry.... habe ich das ins falsche Forum reingeschrieben? Also danke erstmal für die Codevorschläge, aber das ist kein C# Code mit dem ich eigentlich arbeite.... 

    .::datekk::.


    • Bearbeitet datekk2 Dienstag, 31. Dezember 2019 10:53
    Dienstag, 31. Dezember 2019 10:52
  • Hi,

    nö, ins falsche Forum nicht unbedingt. Aber es gibt halt x verschiedene Sprachen in .NET, daher ist es zwingend notwendig, diese mit anzugeben.

    Du kannst den Code aber recht problemlos mit einem Onlinekonverter wie bspw. http://converter.telerik.com/ übersetzen lassen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Dienstag, 31. Dezember 2019 11:58
    Moderator
  • Ah ok.. Danke für den Converter Link.

    Ich habe es nun doch mit dem WebClienten umgesetzt, weil es hiermit doch sehr einfach geht. 

    Ich habe eine neue Methode erstellt: LoadAsStream

            public static byte[] LoadAsStream (string url)
            {
    
                byte[] buffer;
                using (WebClient client = new WebClient())
                {
                    
                    buffer = client.DownloadData(url);
    
                }
    
                return buffer;
    
    
    
            }

    Im Programm selbst habe ich dann einfach folgendes angewendet:

    Bilder bilder = new Bilder();
    
    Bilder.Bild = LoadAsStream(url);
    
    db.Tabelle.Add(tabelle);
    db.SaveChanges();
    


    .::datekk::.

    • Als Antwort markiert datekk2 Dienstag, 7. Januar 2020 10:37
    Dienstag, 31. Dezember 2019 12:14
  • Hi,
    das geht mit HttpClient genau so einfach:

        public async Task<byte[]> DownloadFile(String url)
        {
          using (HttpResponseMessage result = await Client.GetAsync(url))
            if (result.IsSuccessStatusCode) return await result.Content.ReadAsByteArrayAsync();
          return null;
        }

    HttpClient wird als statische Eigenschaft bereitgestellt:

        private static HttpClient _client = null;
        public static HttpClient Client
        {
          get
          {
            if (_client == null) _client = new HttpClient();
            return _client;
          }
        }

    Die Kapselung in einer Klasse könnte so aussehen:

    using System;
    using System.Data.SqlClient;
    using System.Net.Http;
    using System.Threading.Tasks;
    
    namespace ConsoleApp1
    {
      class Demo02
      {
        public async void Execute(String rootPath, String filename)
        {
          var buf = await DownloadFile($"{rootPath}/{filename}");
          if (buf != null)
            using (SqlConnection cn = new SqlConnection(Settings.CnSQL))
            {
              cn.Open();
              using (SqlCommand cmd = new SqlCommand("INSERT INTO Pictures(image) VALUES(@Img)", cn))
              {
                cmd.Parameters.AddWithValue("@img", buf);
                cmd.ExecuteNonQuery();
              }
            }
        }
    
        public async Task<byte[]> DownloadFile(String url)
        {
          using (HttpResponseMessage result = await Client.GetAsync(url))
            if (result.IsSuccessStatusCode) return await result.Content.ReadAsByteArrayAsync();
          return null;
        }
    
        private static HttpClient _client = null;
        public static HttpClient Client
        {
          get
          {
            if (_client == null) _client = new HttpClient();
            return _client;
          }
        }
      }
    }

    Der Aufruf kann so aussehen:

            (new Demo02()).Execute(Settings.RootPath, Settings.FileName);

    wobei Settings eine statische Klasse mit den Parametern ist.


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    Dienstag, 31. Dezember 2019 19:07