Ich habe einen REST-Webdienst, der derzeit diese URL verfügbar macht:
http: // server / data / media
wo Benutzer können POST
die folgenden JSON:
{
"Name": "Test",
"Latitude": 12.59817,
"Longitude": 52.12873
}
um neue Medienmetadaten zu erstellen.
Jetzt muss ich die Möglichkeit haben, eine Datei gleichzeitig mit den Medienmetadaten hochzuladen. Was ist der beste Weg, dies zu tun? Ich könnte eine neue Eigenschaft namens " file
base64" einführen und die Datei codieren, aber ich habe mich gefragt, ob es einen besseren Weg gibt.
Es wird auch verwendet, multipart/form-data
wie ein HTML-Formular senden würde, aber ich verwende einen REST-Webdienst und möchte, wenn möglich, bei der Verwendung von JSON bleiben.
web-services
json
rest
file-upload
Daniel T.
quelle
quelle
Antworten:
Ich stimme Greg zu, dass ein Zwei-Phasen-Ansatz eine vernünftige Lösung ist, aber ich würde es umgekehrt machen. Ich würde tun:
So erstellen Sie den Metadateneintrag und geben eine Antwort zurück wie:
Der Client kann dann diese ContentUrl verwenden und einen PUT mit den Dateidaten durchführen.
Das Schöne an diesem Ansatz ist, dass die URL, die Sie zurückgeben, nur auf einen anderen Server mit mehr Speicherplatz / Kapazität verweisen kann, wenn Ihr Server mit immensen Datenmengen belastet wird. Oder Sie könnten einen Round-Robin-Ansatz implementieren, wenn die Bandbreite ein Problem darstellt.
quelle
Nur weil Sie nicht den gesamten Anforderungshauptteil in JSON einschließen, bedeutet dies nicht, dass es nicht RESTful ist,
multipart/form-data
sowohl JSON als auch die Datei (en) in einer einzigen Anforderung zu veröffentlichen:auf der Serverseite (mit Python als Pseudocode):
Um mehrere Dateien hochzuladen, können Sie entweder separate "Formularfelder" für jedes verwenden:
... in diesem Fall hat der Servercode
request.args['file1'][0]
undrequest.args['file2'][0]
oder verwenden Sie das gleiche für viele:
... in diesem Fall
request.args['files']
wird einfach eine Liste der Länge 2 sein.oder übergeben Sie mehrere Dateien durch ein einzelnes Feld:
... in diesem Fall
request.args['files']
wird es eine Zeichenfolge sein, die alle Dateien enthält, die Sie selbst analysieren müssen - nicht sicher, wie es geht, aber ich bin sicher, dass es nicht schwierig ist, oder besser nur die vorherigen Ansätze verwenden.Der Unterschied zwischen
@
und<
besteht darin,@
dass die Datei als Datei-Upload angehängt wird, während<
der Inhalt der Datei als Textfeld angehängt wird .PS Nur weil ich
curl
diePOST
Anforderungen generiere , heißt das nicht, dass nicht genau dieselben HTTP-Anforderungen von einer Programmiersprache wie Python oder einem ausreichend leistungsfähigen Tool gesendet werden konnten.quelle
curl -f 'metadata={"foo": "bar"}'
?Eine Möglichkeit, sich dem Problem zu nähern, besteht darin, den Upload in zwei Phasen durchzuführen. Zunächst laden Sie die Datei selbst mithilfe eines POST hoch, wobei der Server eine Kennung an den Client zurückgibt (eine Kennung kann die SHA1 des Dateiinhalts sein). Dann ordnet eine zweite Anforderung die Metadaten den Dateidaten zu:
Durch die Einbeziehung der in die JSON-Anforderung selbst codierten Datei data64 64 wird die Größe der übertragenen Daten um 33% erhöht. Dies kann abhängig von der Gesamtgröße der Datei wichtig sein oder auch nicht.
Ein anderer Ansatz könnte darin bestehen, einen POST der Rohdateidaten zu verwenden, jedoch alle Metadaten in den HTTP-Anforderungsheader aufzunehmen. Dies liegt jedoch etwas außerhalb der grundlegenden REST-Operationen und kann für einige HTTP-Client-Bibliotheken umständlicher sein.
quelle
Mir ist klar, dass dies eine sehr alte Frage ist, aber hoffentlich hilft dies jemand anderem, als ich auf diesen Beitrag stieß und nach dem gleichen suchte. Ich hatte ein ähnliches Problem, nur dass meine Metadaten Guid und Int waren. Die Lösung ist jedoch dieselbe. Sie können die benötigten Metadaten einfach in die URL aufnehmen.
POST-Akzeptanzmethode in Ihrer "Controller" -Klasse:
Dann, in was auch immer Sie Routen registrieren, WebApiConfig.Register (HttpConfiguration config) für mich in diesem Fall.
quelle
Wenn Ihre Datei und ihre Metadaten eine Ressource erstellen, ist es vollkommen in Ordnung, beide in einer Anfrage hochzuladen. Beispielanforderung wäre:
quelle
Ich verstehe nicht, warum im Laufe von acht Jahren niemand die einfache Antwort veröffentlicht hat. Codieren Sie den json nicht als base64, sondern als Zeichenfolge. Dann dekodieren Sie einfach den JSON auf der Serverseite.
In Javascript:
POST es mit Content-Type: Multipart / Formulardaten
Rufen Sie auf der Serverseite die Datei normal ab und rufen Sie den JSON als Zeichenfolge ab. Konvertieren Sie die Zeichenfolge in ein Objekt, bei dem es sich normalerweise um eine Codezeile handelt, unabhängig davon, welche Programmiersprache Sie verwenden.
(Ja, es funktioniert großartig. In einer meiner Apps.)
quelle