Eu tenho um serviço web REST que atualmente expõe este URL:
http: // servidor / dados / mídia
onde os usuários podem POST
o seguinte JSON:
{
"Name": "Test",
"Latitude": 12.59817,
"Longitude": 52.12873
}
para criar um novo metadado de mídia.
Agora, preciso fazer o upload de um arquivo ao mesmo tempo que os metadados da mídia. Qual é a melhor maneira de fazer isso? Eu poderia introduzir uma nova propriedade chamada file
e base64 codificar o arquivo, mas queria saber se havia uma maneira melhor.
Também multipart/form-data
estou usando como o que um formulário HTML enviaria, mas estou usando um serviço da Web REST e quero continuar usando JSON, se possível.
web-services
json
rest
file-upload
Daniel T.
fonte
fonte
Respostas:
Concordo com Greg que uma abordagem em duas fases é uma solução razoável, mas eu faria o contrário. Eu faria:
Para criar a entrada de metadados e retornar uma resposta como:
O cliente pode então usar este ContentUrl e fazer um PUT com os dados do arquivo.
O ponto positivo dessa abordagem é que, quando o servidor começa a ficar sobrecarregado com imensos volumes de dados, a URL retornada pode apenas apontar para outro servidor com mais espaço / capacidade. Ou você pode implementar algum tipo de abordagem round robin se a largura de banda for um problema.
fonte
Só porque você não está agrupando todo o corpo da solicitação no JSON, não significa que não seja RESTful usar
multipart/form-data
para postar o JSON e o (s) arquivo (s) em uma única solicitação:no lado do servidor (usando Python para pseudocódigo):
para carregar vários arquivos, é possível usar "campos de formulário" separados para cada um:
... nesse caso, o código do servidor terá
request.args['file1'][0]
erequest.args['file2'][0]
ou reutilize o mesmo para muitos:
... nesse caso
request.args['files']
será simplesmente uma lista de comprimento 2.ou passe vários arquivos por um único campo:
... nesse caso
request.args['files']
, será uma string contendo todos os arquivos, que você terá que analisar por conta própria - não sabe como fazê-lo, mas tenho certeza de que não é difícil, ou melhor, use as abordagens anteriores.A diferença entre
@
e<
é que@
faz com que o arquivo seja anexado como um upload de arquivo, enquanto<
anexa o conteúdo do arquivo como um campo de texto.PS Só porque estou usando
curl
como uma forma de gerarPOST
solicitações não significa que as mesmas solicitações HTTP não puderam ser enviadas de uma linguagem de programação como Python ou usando qualquer ferramenta com capacidade suficiente.fonte
curl -f 'metadata={"foo": "bar"}'
?Uma maneira de abordar o problema é fazer do upload um processo de duas fases. Primeiro, você faria o upload do próprio arquivo usando um POST, em que o servidor retornará algum identificador de volta ao cliente (um identificador pode ser o SHA1 do conteúdo do arquivo). Em seguida, uma segunda solicitação associa os metadados aos dados do arquivo:
A inclusão da base de dados do arquivo64 codificada na própria solicitação JSON aumentará o tamanho dos dados transferidos em 33%. Isso pode ou não ser importante, dependendo do tamanho geral do arquivo.
Outra abordagem pode ser usar um POST dos dados brutos do arquivo, mas incluir quaisquer metadados no cabeçalho da solicitação HTTP. No entanto, isso fica um pouco fora das operações REST básicas e pode ser mais complicado para algumas bibliotecas de clientes HTTP.
fonte
Sei que essa é uma pergunta muito antiga, mas espero que isso ajude outra pessoa quando cheguei neste post procurando a mesma coisa. Eu tive um problema semelhante, apenas que meus metadados eram Guid e int. A solução é a mesma. Você pode apenas tornar os metadados necessários parte do URL.
Método de aceitação POST na sua classe "Controller":
Então, no que quer que você esteja registrando rotas, WebApiConfig.Register (HttpConfiguration config) para mim nesse caso.
fonte
Se o seu arquivo e seus metadados criarem um recurso, é perfeitamente bom fazer o upload dos dois em uma solicitação. A solicitação de amostra seria:
fonte
Não entendo por que, ao longo de oito anos, ninguém postou a resposta fácil. Em vez de codificar o arquivo como base64, codifique o json como uma sequência. Em seguida, decodifique o json no lado do servidor.
Em Javascript:
POSTA-O usando o Tipo de Conteúdo: multipart / form-data
No lado do servidor, recupere o arquivo normalmente e recupere o json como uma sequência. Converta a string em um objeto, que geralmente é uma linha de código, independentemente da linguagem de programação usada.
(Sim, funciona muito bem. Fazê-lo em um dos meus aplicativos.)
fonte