web-dev-qa-db-fra.com

Envoi HTTP POST Champ multipart / form-data utilisant RestSharp

Je rencontre des problèmes avec RestSharp pour une API REST que je dois utiliser pour un projet sur lequel je travaille. La demande que je dois émettre se compose de trois parties: une clé API d'en-tête, une clé fichier à télécharger, et un tas de données au format JSON. L'API requiert que la partie de données soit envoyée en utilisant un nom de champ de formulaire de "données". Pour une raison quelconque, cela pose problème car il nomme le champ "données" dans le corps de la demande.

Le code que j'ai comme suit est le suivant:

var request = new RestRequest(UPLOAD_DOC_URLSEGMENT, Method.POST)
{
    RequestFormat = DataFormat.Json,
    AlwaysMultipartFormData = true,
    JsonSerializer = new RestSharpJsonDotNetSerializer(customSerializer)
};

if (doc is DocA)
    request.AddParameter("data",doc as DocA,ParameterType.RequestBody);
    //request.AddBody(doc as DocA);
else
    request.AddParameter("data", doc as DocB,ParameterType.RequestBody);
    //request.AddBody(doc as DocB);

request.AddFile("file", doc.File.FullName);

Comme vous pouvez le voir, j'ai essayé d'utiliser à la fois la méthode request.AddBody(doc) et la méthode request.AddParameter(name, object, type). Aucun d'eux ne semble envoyer les données correctement car je reçois une réponse du serveur me disant que les paramètres requis sont manquants. En utilisant fiddler, je peux voir les données binaires, mais jamais les données JSON avec ces deux méthodes. J'ai parcouru la documentation RestSharp, mais je ne trouve rien qui me permette de spécifier un nom de "champ" particulier en tant que "données" pour le corps de données du formulaire, ce qui est, à mon avis, à l'origine du problème que j'ai. . Qu'est-ce que je fais mal ici?

EDIT: Après une inspection plus approfondie avec le violoneux, il semble qu'il n'ajoute pas du tout mes données JSON au corps de la demande HTTP. Cependant, avec un point d'arrêt juste avant le téléchargement (commande d'exécution), je peux tout voir sérialisé correctement dans la liste des paramètres (et la liste des fichiers). Lorsque j'inspecte le avec Fiddler, je vois les données binaires du fichier, puis une limite multipart/form-data, puis rien. Je suppose que c'est là que mes données sont censées être ...

18
JNYRanger

Je fais donc cela en contournant un problème avec l'utilisation de la méthode AddBody qui tue automatiquement les images de formulaire en plusieurs parties et ne les enverra pas. Vous devez plutôt utiliser l'ajout d'un paramètre.

Pour résoudre ce problème, vous devrez peut-être effectuer un petit travail des deux côtés de la communication.

Pour envoyer le message du client, procédez comme suit:

new RestRequest("<Your URI>");
request.AddParameter("request", tokenRequest.ToJson());
request.AddFile("front", frontImage.CopyTo, "front");
request.AddFile("back", backImage.CopyTo, "back");
request.AddHeader("Content-Type", "multipart/form-data");

Du côté de mon service Web, j'accepte le json comme argument de la méthode et j'obtiens manuellement une référence aux flux de fichiers:

public JsonResult MyService(StoreImageRequest request)
{
    var frontImage = HttpContext.Request.Files["front"].InputStream;
    var backImage = HttpContext.Request.Files["front"].InputStream;
}
11
C Tierney

Si votre serveur peut traiter une multi-partie avec le corps JSON et les parties Files, alors:

        var req = new RestRequest(UPLOAD_DOC_URLSEGMENT, Method.POST);

        req.RequestFormat = DataFormat.Json;
        req.AddBody(doc);

        req.AddFileBytes("TestImage", Properties.Resources.TestImage, "TestImage.jpg");

        req.AddHeader("apikey", "MY-API-KEY");
        var resp = restClient.Execute<ApiResult>(req);

Côté serveur, cette demande en plusieurs parties doit être traitée comme suit:

    [HttpPost]
    public JsonResult UploadDoc()
    {
        // This is multipart request. So we should get JSON from http form part:
        MyDocModel doc = JsonConvert.DeserializeObject<MyDocModel>(Request.Form[0]);

        foreach (string fileName in request.Files)
        {
            HttpPostedFileBase file = request.Files[fileName];
        }
0
epox