Upload über API /service/api/upload

cancel
Showing results for 
Search instead for 
Did you mean: 
martinn
Member II

Upload über API /service/api/upload

Hallo,
Hat jemand bereits erfolgreich einen Upload mit dem Webscript /service/api/upload hinbekommen?
Ich habe das Webscript angesehen und m.E. alle erforderlichen Parameter gefüllt.
Dennoch erhalte ich hier bei Ausführung immer ein "The remote server returned an error: (500) Internal Server Error.".


       //Authentication succeded
      //…….

      //set mimetype
      strMimetype = GetMimeType(strFileName);

      //encode the content of the file
      strFileEncContent = base64Encode(strFilePath);

      //the Json string has to be created
      strJson = "{filedata: {filename: \"" + strFileName + "\", \"content\": \"" + strFileEncContent + "\", \"mimetype\": \"" + strMimetype + "\"},";
      strJson = strJson + "filename : \"" + strFileName + "\",";
      strJson = strJson + "destination : \"" + this.locationUuid + "\",";
      strJson = strJson + "description : \"" + this.tbDescription.Text + " \",";
      strJson = strJson + "aspects : \"" + Constants.ASPECT_VERSIONABLE + "," + Constants.ASPECT_CLASSIFIABLE + "\",";
      strJson = strJson + "uploaddirectory : \"" + "DIMS! Archive" + "\"}";

      //get these setting and create a url and add the ticket.
      //uploadPath  is set to  "http://localhost:8080/alfresco/service/api/upload"
      strUri = Properties.Settings.Default.strUploadPath.ToString();              
      strTemp = string.Concat(strUri, "?", strTicket);

      webRequest = WebRequest.Create(strTemp);
      webRequest.Method = "POST";
      webRequest.ContentType = "application/json";

      if (strUri != "")
      {
         // write out the data to the web server
         writeToURL(webRequest, strJson);

        //read the response from the Web Server
        strHtmlContent = retrieveFromURL(webRequest);
        MessageBox.Show(strFilePath + " uploaded");
     }
   catch (Exception ex)
   {
      MessageBox.Show("Error: Upload error! Original error: " + ex.Message);
      MessageBox.Show(ex.StackTrace);
   }     
Wenn jetzt Parameter fehlen würden so müsste lt. Webscript ein "Required parameters are missing" als Antwort kommen.
Es kommt jedoch zur o.g. Fehlermeldung. Was ist falsch?
Kann mir jemand einen Tip geben oder ein funktionierendes Beispiel?
Edit: ich nutze Alfresco Vers. 3.4.d
8 Replies
jpfi_4454
Member II

Re: Upload über API /service/api/upload

Hi,
du versuchts es hier mit dem falschen Mimetype (json). Das WebScript erwartet einen application/x-www-form-urlencoded POST-Body.
JSON bekommst du als Response.
VG, jan
martinn
Member II

Re: Upload über API /service/api/upload

Danke für die schnelle Antwort.
Nun habe ich dann geschrieben:

            //encode the content of the file
            strFileEncContent = base64Encode(strFilePath);

            strData = "filename=" + strFileName + "& content=" + strFileEncContent + "&mimetype=" + strMimetype;
            strData = strData + "&filename=" + strFileName ;
            strData = strData + "&destination=" + this.locationUuid;
            strData = strData + "&description=" + this.tbDescription.Text;
            strData = strData + "&aspects=" + Constants.ASPECT_VERSIONABLE + "," + Constants.ASPECT_CLASSIFIABLE;
            strData = strData + "&uploaddirectory=" + "DIMS! Archive";

            byte[] byteArray = Encoding.UTF8.GetBytes(strData);

            //get these setting and create a url and add the ticket.
            strUri = Properties.Settings.Default.strUploadPath.ToString();
            strTemp = string.Concat(strUri, "?", strTicket);

            webRequest = WebRequest.Create(strTemp);
            webRequest.Method = "POST";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.ContentLength = byteArray.Length;
                       

und dennoch erhalte ich weiterhin den Error 500. Vielleicht sehe ich auch den Wald vor lauter Bäumen nicht.
Aber ein wenig bessere Doku und/oder Beispiele, die auch für Neulinge verständlich sind, sollte es schon geben.
jpfi_4454
Member II

Re: Upload über API /service/api/upload

Hi,
wo sendest du dein byte[] byteArray an den Server?
Du musst deine bytes auch an den Server streamen.
VG, Jan
martinn
Member II

Re: Upload über API /service/api/upload

Hi,
wo sendest du dein byte[] byteArray an den Server?
Du musst deine bytes auch an den Server streamen.
VG, Jan

Sorry, ich dachte das wäre bereits klar. Denn in meinem ersten Post war die Funktion "writeToURL" im Code erwähnt. Im 2.Post habe ich dann nur die Änderungen gepostet.
Mittlerweile habe ich das Erstellen des Daten etwas geändert, so das sie folgende Struktur haben:

{
   filedata=
   {
      filename = <Wert>,   
      content  = <Wert>,         
      mimetype = <Wert>
   },
   filename  =  <Wert>,
   destination = <Wert>,
   description = <Wert>,
   aspects      = <Wert>,
   uploaddirectory = <Wert>
}

Denn ich vermute den Fehler irgendwo beim Erstellen dieser Daten. Aber bis jetzt hat das auch nichts gebracht. Der Fehlercode 500 kommt dennoch.
Hier nochmal zur Verdeutlichung die aktuelle Version:


   try
   {
      //… Authentication succeded, Ticket is strTicket
     
      // Display a wait cursor while the file is uploaded
      Cursor.Current = Cursors.WaitCursor;

      //now try to upload the file
      strMimetype = GetMimeType(strFileName);

      //encode the content of the file
      strFileEncContent = base64Encode(strFilePath);
      string strAspects = Constants.ASPECT_VERSIONABLE + "," + Constants.ASPECT_CLASSIFIABLE;
      fileData = new ArrayList();
      arrData = new ArrayList();

      strFileEncContent = base64Encode(strFilePath);
      strAspects = Constants.ASPECT_VERSIONABLE + "," + Constants.ASPECT_CLASSIFIABLE;
      fileData = new ArrayList();
      arrData = new ArrayList();

      fileData.Add(String.Format("{0}={1}", "filename", strFileName));
      fileData.Add(String.Format("{0}={1}", "content", strFileEncContent));
      fileData.Add(String.Format("{0}={1}", "mimetype", strMimetype));
      strFileData = String.Join("&", (String[])fileData.ToArray(typeof(string)));

      arrData.Add(String.Format("{0}={1}", "filedata", strFileData));
      arrData.Add(String.Format("{0}={1}", "filename", strFileName));
      arrData.Add(String.Format("{0}={1}", "destination", this.locationUuid));
      arrData.Add(String.Format("{0}={1}", "description", this.tbDescription.Text));
      arrData.Add(String.Format("{0}={1}", "aspects", strAspects));
      arrData.Add(String.Format("{0}={1}", "uploaddirectory", "TheArchive"));

      strParameters = String.Join("&", (String[])arrData.ToArray(typeof(string)));

      byte[] byteArray = Encoding.UTF8.GetBytes(strParameters);

      //get these setting and create a url and add the ticket.
      strUri = Properties.Settings.Default.strUploadPath.ToString();
      strTemp = string.Concat(strUri, "?", strTicket);

      webRequest = WebRequest.Create(strTemp);
      webRequest.Method = "POST";
      webRequest.ContentType = "application/x-www-form-urlencoded";
      webRequest.ContentLength = byteArray.Length;
     
      if (strUri != null)
      {
         // write out the data to the web server
         writeToURL(webRequest, byteArray);
      }
      else
      {
         webRequest.ContentLength = 0;
      }
      // read the response from the Web Server
      strHtmlContent = retrieveFromURL(webRequest);
      //———————————————————————————————————-
      // Reset the cursor to the default for all controls.
      Cursor.Current = Cursors.Default;

      MessageBox.Show(strFilePath + " uploaded");
   }
    catch (Exception ex)
   {
      MessageBox.Show("Error: Upload error! Original error: " + ex.Message);
      MessageBox.Show(ex.StackTrace);
   }

und die Funktion writeToUrl ist hier:

      void writeToURL(WebRequest request, byte[] bytes)
      {
         request.ContentLength = bytes.Length;
         // 1. Get an output stream from the request object
         Stream outputStream = request.GetRequestStream();

         // 2. Post the data out to the stream
         outputStream.Write(bytes, 0, bytes.Length);

         // 3. Close the output stream and send the data out to the web server
         outputStream.Close();
      }// end writeToURL method

Und erst einmal Danke für die Mühe.
jpfi_4454
Member II

Re: Upload über API /service/api/upload

Hi,
ok, dann lass uns hier mal eine vernünftige Analyse betreiben. Ich bin kein c#-kenner…
Schneide mal bitte deinen HTTP-Traffic mit HTTPAnalyzer o.ä. mit und poste den Request und die Response.
Alternativ solltest du dich mal am JS-Debugger von Alfresco versuchen: http://wiki.alfresco.com/wiki/Web_Scripts#Debugging_a_Controller_Script
VG, Jan
martinn
Member II

Re: Upload über API /service/api/upload

Hi,
ok, dann lass uns hier mal eine vernünftige Analyse betreiben. Ich bin kein c#-kenner…
Schneide mal bitte deinen HTTP-Traffic mit HTTPAnalyzer o.ä. mit und poste den Request und die Response.
Alternativ solltest du dich mal am JS-Debugger von Alfresco versuchen: http://wiki.alfresco.com/wiki/Web_Scripts#Debugging_a_Controller_Script
VG, Jan

Danke für Deine Antwort. Leider hab ich keinerlei Erfahrung mit solchen Tools und weiss gar nicht wie das bedient werden muss etc.
Bislang brauchte ich für meine Web- u.a. Entwicklungen so etwas nicht. Aber das ist ein anderes Thema.

Danke für den Link. Ok, ich werde mal sehen ob ich mit dem Debugger was herausfinden kann.
Eine Bemerkung sei dennoch erlaubt: Da ist Software entwickelt worden und, so denke ich, auch getestet. Um nun solche Webscripts zu testen muss der Tester doch Http-Seiten, Scripte oder irgend etwas haben, damit er sehen kann ob es funktioniert. Solche *Testdinge* wären doch die besten Beispiele an denen man sehen und lernen kann, wie Alfresco mit anderer Software kommuniziert.
Oder nur ein einfaches Beispiel in der Dokumentation würde auch schon reichen.
Ich werde mich hier wieder melden, wenn ich was herausgefunden habe.
martinn
Member II

Re: Upload über API /service/api/upload

Hi,
du versuchts es hier mit dem falschen Mimetype (json). Das WebScript erwartet einen application/x-www-form-urlencoded POST-Body.
JSON bekommst du als Response.
VG, jan

Wo bitte ist das dokumentiert? Denn diese Aussage kann so nicht stimmen, denn ich habe jetzt mit dem Debugger sehen können, das bei Verwendung dieses Content-Types kein Part "form-data" empfangen wird. Daher gibt der Debugger dann auch die Fehlermeldung aus 'org.mozilla.javascript.ecmaerror referenceerror formdata" is not defined'.
Wenn ich mit "multipart/form-data" sende, dann ist dieser Part da.
Hier gibt es dann auch das Array "Fields" welches vom Webscript in einer Schleife gelesen wird. Leider fehlen hier drin die Felder, obwohl ich in meinem Code glaube diese gefüllt zu haben.
An dieser Stelle wäre ein Beispiel, das zeigt wie man die Daten richtig zusammenstellen soll wirklich hilfreich. Ja, ich habe auch nach so etwas die Tanten Google und Wiki befragt.
Hier gibt es etliche Möglichkeiten. Muss ich die jetzt alle der Reihe nach ausprobieren? Oder könnte hier von Insiderseite mal ein Hinweis in die richtige Richtung erfolgen?
Danke für die Mühe im Voraus.
ddanninger
Member II

Re: Upload über API /service/api/upload

hallo,
mit dem upload stimmt was nicht wie du schon bemerkt hast. (filedata usw)  du schreibst alles auch händisch hinein in filedata aber es fehlt die simulation eines "file uploads":

normalerweise sollte ja etwas wie …

Content-Disposition: form-data; name=…..

mitgeschickt werden für die files. also dein post sollte ja ein multipart/form-data post sein.

Ich bin mir sicher unter C# gibt es eine funktion wie z.B UploadFile oder AddFile oder ähnliches ….. http://aspnetupload.com/Upload-File-POST-HttpWebRequest-WebClient-RFC-1867.aspx weiß das jetzt nicht auswendig ansonsten wirst du mit "c# webclient post file" oder ähnlichen sicher genug snippets dazu finden.

Das sollte dann den file upload simulieren und damit ist hoffe ich dein problem gelöst

Lg
Dom