none
Datei Upload per JavaScript oder jQuery RRS feed

  • Frage

  • Hallo,
    ein oder mehrere Dateien sollen im Intranet vom Client auf einen Fileserver hochgeladen werden.
    Ich hab dazu auch schon etliche Tutorial gesichtet, stehe aber ehrlich gesagt total auf dem Schlauch.
    Soweit ich das verstanden habe, läuft das doch nur per HTTP-Request, d.h. es funktioniert per Ajax?

    Was muss ich denn da an Parametern übergeben und wie muss dann die Serverseitige Behandlung ausschauen?
    Zur Info: Der IIS (webserver.firma.local) liegt separat vom Fileserver (x.x.x.20). Das abholen und speichern der Daten aus der Datenbank an sich erfolgt nur über Webservices, die am selben IIS, aber in einer separaten Instanz gehostet wird (wcf.firma.local).

    Zum Einsatz kommt in einer WebPages-Anwendung pures JavaScript und jQuery. Nur beim ersten Aufruf der Seite wird ein Request zum Server abgesetzt und einige Elemente per Razor befüllt. Es ist aber keine MVC-Anwendung.

    Die Dateien zum Upload stehen in einer ungebundenen Liste zur Verfügung (ich hab mich da an diesem Beispiel orientiert).

    Doch ich hab absolut keinen Dunst, wie ich das dann im Webservice (VB.NET) weiterverarbeiten muss oder wie ich einzelnen Dateien per Paremeter erst einmal überhaupt dahin schicke.
    :/

    In der Hoffnung, mich einigermaßen verständlich ausgedrückt zu haben, wäre es wirklich toll, wenn mir vielleicht der ein oder andere da ein bissel auf Sprünge helfen könnte.

    Vielen Dank und ein schönes Wochenende


    Viele Grüße, Volker


    • Bearbeitet Volker S Freitag, 22. September 2017 11:15
    Freitag, 22. September 2017 11:14

Antworten

Alle Antworten

  • Hallo Volker,
    das ist sicher nicht das womit ich mich täglich beschäftige, lass es mich trotzdem versuchen Dir zu helfen.
    Zunächst meine ich es sind 2 Teile. 
    Der 1. Teil ist der Weg von der Web-Seite zu deinem dahinterliegenden Controller / WEBAPI / Quelltext.
    der 2. Teil ist die Frage was zu tun ist damit die Datei nun gespeichert wird.
    1.
    https://forums.asp.net/t/2077847.aspx?C+Web+API+jQuery+File+Upload
    Das Beispiel kann schon helfen.
    Aus meiner Sicht zeigt es wie es von der Webseite zum Controller geht. oder: aus dem Teil mit JQuery in den Teil mit c#/VB. 
    Nun kommt der Teil der mir nicht ganz klar ist ob Du das so schon umsetzten kannst.
    Du schreibst ja Du hättest einen Webservice.
    1. Einfachste Variante wäre den Webservice zu erweitern um die WEBAPI.
    2. Eine Variante mit Webservice wird hier gezeigt: https://support.microsoft.com/de-de/help/318425/how-to-send-and-receive-binary-documents-by-using-an-asp-net-web-servi

    Wenn also die Datei erstmal im Controller/ der dahinterliegenden Webmethod angekommen ist kommt die Frage nach dem Speichern.
    Nun braucht der webserver zugriff auf den Fileserver. Die Zugriffsrechte des IIS-ServiceAccounts / APPPools sind nun die passen müssen. Das Schreiben ins  passende Verzeichnis des Fileservers muss erlaubt sein.

    Hier etwas zu diesem Schritt:
    https://stackoverflow.com/questions/22240439/granting-write-permissions-to-a-networked-unc-folder-for-asp-net-under-iis-7-5-a

    HTH

    Grüße Alexander

    Samstag, 23. September 2017 09:38
  • Hallo Alexander,
    vielen Dank für dein Interesse.
    Hmm, mit WEB-API wollte ich mich eigentlich nicht herumschlagen. Da hab ich absolut keinerlei blassen Schimmer, weil noch nie damit beschäftigt.

    Variante 2.2 klingt für mich erst einmal am verständlichsten. Jedoch stellt sich mir die Frage, wie übergebe ich denn die Dateien mit JS/jQuery als Bytearray an die AJAX-Funktion?

    Vielleicht nochmals zur Verständigung: Am Client kommt eine ASP.NET WebPages-Lösung zum Einsatz, also ganz ohne Controller, Views, etc. (damit hab ich nix am Hut).
    Als WebService setze ich AJAX-fähige WCF-Dienste ein. Dort verarbeite ich alles per VB.
    Im Grunde baue ich mehr oder weniger eine "fast" SinglePageApp, d.h. ich setzte schon verschiedene .vbhtml-Seiten ein, diese trenne ich aber nach Themen. Also möchte ich auf PageRequests größtenteils verzichten und daher soweit es geht alles mittels Webdiensten mit jQuery-AJAX lösen.

    Ich weiß auch nicht, ob ich mit der Methode auf dem Holzweg bin und man das evtl. ganz anders lösen könnte?


    Viele Grüße, Volker

    Montag, 25. September 2017 10:54
  • Hallo,
    ich nochmal.
    Also ich hab es jetzt soweit, dass der Ajax-Aufruf zumindest ein 'OK' als Status zurück gibt.

    Jedoch hab ich keine Ahnung, wie ich die Datei am WebService annehme. Sobald ein Parameter in der Funktion steht, gibt es eine Fehler. Also kann das doch nur über den HTTP-Context, oder was weiß ich, laufen?

    Ich hab mir schon einen Wolf gesucht, finde aber kein aussagekräftiges Beispiel. Fast ausschließlich die Entgegennahme durch PHP. Oder ab und an mit .asmx-Services.

    Als Beispiel der Ajax-Aufruf:

    function fnUpload() {
      var Type = "POST";
      var ContentType = "application/json; charset=utf-8";
      var Url = '/Services/Service.svc/fnGetFile';
      var Data = new FormData();
      var files = $("#FileUpload")[0].files;
      Data.append("file", files[0]);
    
      $.ajax({
       type: Type,
       processData: false,
       contentType: ContentType,
       url: Url,
       data: Data,
       success: function (result) {      
         $("#divFileUploaded").append("hochgeladen");
       },
      error: function (result) {
         $("#divUploaded").append(result);
       }
      })
     }
    

    ...und hier muss jetzt das ganze Zeugs irgendwie verarbeitet werden:

    <OperationContract()>
    <WebInvoke(Method:="POST")>
    Public Function fnGetFile() As String
    
       'irgendwie die Datei entgegennehmen und verarbeiten
    
    End Function
    
    Wäre schön, wenn jemand noch eine Idee hätte.


    Viele Grüße, Volker

    Mittwoch, 4. Oktober 2017 12:28
  • Hallo Volker,

    wenn Du eine Singel Page Applikation hast und dabei bleiben willst, kommst Du um ein Controller nicht rum. Irgendwas muss ja die Daten annehmen. Ich habe vor ein paar Tage für ein anderen Thread eine Beispiel WebApi geschrieben und sie auf Github gepackt. Der Client ist in diesem fall eine UWP App. Macht aber nix da sich die API ja nicht ändert. Alles wichtige findest Du im DataColtroller. Die Projektart ist ASP.NET Core 2 WebAPI

    In JS könnte das dann so aussehen

    $('.fileUpload').on('change', '#DokumentenUpload', function (e) {
            
            e.preventDefault();
            var files = this.files;
    
            var fd = new FormData();
            fd.append('file', files[0])
    
            var jqXHR = $.ajax({
                url: uploadURL,
                type: "POST",
                contentType: false,
                processData: false,
                cache: false,
                data: fd,
                success: function (data) {
    
    	    });
    
    });


    Gruß Thomas

    Sage nie, ich kann es nicht - sage nur, ich kann es noch nicht!

    Icon für UWP

    Cross Platform Canvas for UWP, Android, iOS

    UWP Community Toolkit Sample App

    Alle Größenangaben in UWP müssen durch 4 teilbar sein


    Mittwoch, 4. Oktober 2017 13:08
  • Hallo Thomas,
    danke für dein Interesse.

    Der Webservice laufen nicht im gleichen Content, wie die WebSite. Dafür wird eine separate Website am IIS betrieben.
    Alle anderen Anfragen an andere Funktionen des Webservices (z.B. Datenbankzugriff) laufen ja auch problemlos und ich kann den Service, der die Dateien in Empfang nimmt auch ansprechen.
    Der Ajax-Aufruf meint ja auch das die Datei (oder vielleicht doch nur irgend etwas??) an den Service übergeben wurde und wenn ich den debugge, dann läuft der auch los. Ich weiß eben nur nicht, wie ich was abgreifen muss. Hab es über den HTTPContext.Current.Request.Files versucht, aber da hagelt es nur Fehler ("Diese Methode oder Eigenschaft wird nach dem Aufrufen von HttpRequest.GetBufferlessInputStream nicht unterstützt." )


    Das Projekt von dir hab ich schon entdeckt und mir bereits runtergeladen und etwas drin herum gestöbert.

    Was soll ich sagen... kein Durchblick.

    Ich kann mir halt ehrlich gesagt nicht vorstellen, dass es nur mit Controller usw.  funktioniert.

    Oder ich bin wirklich absolut Ahnungslos...
    Bitte erleuchte mich!
    :/


    Viele Grüße, Volker


    • Bearbeitet Volker S Mittwoch, 4. Oktober 2017 14:06
    Mittwoch, 4. Oktober 2017 14:06
  • Poste doch bitte mal den Code wo die Anfrage ankommt und beschreibe mal bitte was das für ein Webservice ist. Also die Projektart

    In MVC bekommt man das File an die Methode übergeben:

    [HttpPost]

    public JsonResult DropJson(HttpPostedFileBase file, int id) { }



    Gruß Thomas

    Sage nie, ich kann es nicht - sage nur, ich kann es noch nicht!

    Icon für UWP

    Cross Platform Canvas for UWP, Android, iOS

    UWP Community Toolkit Sample App

    Alle Größenangaben in UWP müssen durch 4 teilbar sein



    Mittwoch, 4. Oktober 2017 15:35
  • Hallo Thomas,
    also der Dienst ist ein WCF-Dienst (Ajax fähig) 

    Der besteht aus einer .svc und einer .vb Datei. Eine Schnittstellendatei, irgendwas mit IBlabla.vb, gibt es da nicht.

    In der vb-Datei hab ich halt die ganzen Contracts drin, die mir die Werte liefern, die ich brauche.

    Bsp. Lesen...

        <OperationContract()>
        <WebInvoke(Method:="POST", RequestFormat:=WebMessageFormat.Json, ResponseFormat:=WebMessageFormat.Json)>
        Public Function fnGetProjektInfo(intProjektID As Integer) As List(Of ProMan_vw_PROJEKTINFO)
            Using db As New dbProManEntities
                Dim QUERY = From q In db.vw_PROJEKTINFO
                            Where q.PROJEKT_ID = intProjektID
                            Select q
    
                Return QUERY.ToList
            End Using
        End Function

    ... oder schreiben:

        <OperationContract()>
        <WebInvoke(Method:="POST", RequestFormat:=WebMessageFormat.Json, ResponseFormat:=WebMessageFormat.Json)>
        Public Function fnAenderungNeu(tblAenderung As ProMan_tbl_AENDERUNG) As String
    
            Dim msg As String = ""
            Try
                Using db = New dbProManEntities
                    Dim BID As Integer = tblAenderung.BAUTEIL_ID
    
                    db.Database.ExecuteSqlCommand(String.Format("UPDATE tbl_AENDERUNG SET GESPERRT = 1 WHERE BAUTEIL_ID = {0}", BID))
                    db.tbl_AENDERUNG.Add(tblAenderung)
                    db.SaveChanges()
                    msg = "OK"
                End Using
            Catch ex As Exception
                msg = "Fehler: " & Err.Number & "| \n " & ex.Message
                If Not IsNothing(ex.InnerException) Then
                    msg += " |\n " & ex.InnerException.Message
                End If
            Finally
            End Try
    
            Return msg
    
        End Function

    Da ich von verschiedenen Webanwendungen Daten hole und schicke, hab ich für jede Anwendung einen eigenen Service angelegt und die ganzen Funktionen da rein gepackt. Ob das nun die korrekte Vorgehensweise ist weiß ich auch nicht, jedenfalls funktioniert es so.

    Als Projektart ist das eine ganz normale Website, die aber nur die Services bereitstellt. Da läuft sonst nix weiter.

    Einen Code für die Entgegennahme der Dateien hab ich doch nicht. Ich weiß doch nicht wie und in welcher Form.

    Ich habs erstmal nur an eine leere Funktion geschickt, um überhaupt sehen zu können, ob was ankommt.

        <OperationContract()>
        <WebInvoke(Method:="POST")>
        Public Function fnGetFile(file As HttpPostedFileBase)
    
            'Hier sollte was drinstehen
    
        End Function

    Sobald ich der Methode einen Parameter (welchen Typ auch immer) verpasse, gibt es den Fehler: "Internal Server Error" oder "System.ServiceModel.ServiceActivationException". Ohne Parameter wird die Methode gestartet.


    Viele Grüße, Volker




    • Bearbeitet Volker S Donnerstag, 5. Oktober 2017 06:35
    Donnerstag, 5. Oktober 2017 06:22
  • Ich habe das noch nicht genutzt und ob es richtig ist oder nicht kann ich Dir auch nicht sagen.

    Vielleicht habe ich hier was gefunden was Dir helfen könnte


    Gruß Thomas

    Sage nie, ich kann es nicht - sage nur, ich kann es noch nicht!

    Icon für UWP

    Cross Platform Canvas for UWP, Android, iOS

    UWP Community Toolkit Sample App

    Alle Größenangaben in UWP müssen durch 4 teilbar sein

    • Als Antwort markiert Volker S Montag, 22. Oktober 2018 07:11
    Donnerstag, 5. Oktober 2017 11:21
  • Hallo Thomas,

    das sieht wirklich vielversprechend aus. Werd mir das mal zu Gemüte führen.
    Danke für deine Hilfe.


    Viele Grüße, Volker

    Donnerstag, 5. Oktober 2017 11:41
  • Hey,

    eine gute jQuery Library für Dateiuploads ist: https://blueimp.github.io/jQuery-File-Upload/

    LG

    • Als Antwort vorgeschlagen FraBu81 Freitag, 19. Oktober 2018 06:41
    • Als Antwort markiert Volker S Montag, 22. Oktober 2018 07:11
    Freitag, 19. Oktober 2018 06:41