cURL request in C# Code umwandeln

Dieses Thema im Forum "Programmierung & Entwicklung" wurde erstellt von Affje800, 3. März 2014 .

  1. 3. März 2014
    Hallo,

    ich bin derzeit dabei, ein kleines Framework für die Strava API zu entwickeln. Ich habe allerdings Probleme, eine Datei hochzuladen, der Rest funktioniert ganz gut.
    Ich kann die Datei mit curl hochladen, d.h. es liegt nicht an einem falschen Access Token doer so.

    Hier mal der curl Befehl:

    $ curl -X POST https://www.strava.com/api/v3/uploads \
    -H "Authorization: Bearer 83ebeabdec09f6670863766f792ead24d61fe3f9" \
    -F activity_type=ride \
    -F file=@test.fit \
    -F data_type=fit

    Das Beispiel ist aus der Dokumentation und allgemein gültig. Der Pfad bei file= kann entsprechend angepasst werden.
    Genau dieser Parameter bereitet mir auch Probleme, denn ich weiß nicht, wie ich das ganze in C# umsetzen soll. Ich hätte natürlich als letzte Möglichkeit die Option, curl aus C# aufzurufen, aber das ist unschön und bringt nur unnötige externe Abhängigkeiten ins Programm.

    Allgemeines zum Upload kann man hier finden:
    Strava Uploads V3 API


    Mein bisheriger Code sieht so aus:
    Code:
    public async Task<UploadStatus> UploadActivity(String filePath, DataType dataType, ActivityType activityType = ActivityType.Ride)
     {
     String type = String.Empty;
    
     switch (dataType)
     {
     case DataType.Fit:
     type = "fit";
     break;
     case DataType.FitGZipped:
     type = "fit.gz";
     break;
     case DataType.Gpx:
     type = "gpx";
     break;
     case DataType.GpxGZipped:
     type = "gpx.gz";
     break;
     case DataType.Tcx:
     type = "tcx";
     break;
     case DataType.TcxGZipped:
     type = "tcx.gz";
     break;
     }
    
     //Process activity file
     FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
     byte[] bytes = new byte[fileStream.Length];
     fileStream.Read(bytes, 0, bytes.Length);
    
     //Never forget to close a stream.
     fileStream.Close();
    
     String postUrl = String.Format("{0}?activity_type={1}&data_type={2}&file={3}&access_token={4}", Endpoints.Uploads, activityType, type, fileStream.Name, _authenticator.AccessToken);
    
     //Sending the POST request.
     using (var httpClient = new HttpClient())
     {
     //A Guid is needed for the boundary.
     Guid guid = Guid.NewGuid();
    
     MultipartFormDataContent content = new MultipartFormDataContent(guid.ToString());
     ByteArrayContent byteArray = new ByteArrayContent(bytes);
     byteArray.Headers.Add("file", fileStream.Name);
     content.Add(byteArray);
    
     HttpResponseMessage responseMessage = await httpClient.PostAsync(postUrl, content);
    
     if (responseMessage != null)
     {
     String response = await responseMessage.Content.ReadAsStringAsync();
     Console.WriteLine(response);
     }
     }
    
     //UploadStatus status = Unmarshaller<UploadStatus>.Unmarshal(json);
     //return status;
    
     return null;
     }
    
    Funktioniert aber leider nicht, da der file Parameter ungültig ist. Wie kann ich den POST-Parameter "file" mit dem MultipartFormDataContent "verknüpfen"?
    Ich probiere da schon ewig rum, ich stehe total auf der Leitung.

    Auf der Doku-Seite wird zum file-Parameter nur das folgende angegeben:

    file: multipart/form-data required
    the actual activity data, if gzipped the data_type must end with .gz


    Wäre über hilfreiche Tipps sehr dankbar, denn ich bekomme im Moment ständig den Fehler, dass der file-Parameter ungültig ist ("not a file"). Ich kann ja wohl auch kaum den Inhalt als POST request mitsenden, das sprengt jedes Uri-Limit

    MfG
     
  2. 3. März 2014
    AW: cURL request in C# Code umwandeln

    Hallo!

    Aus den cURL manpages:
    Du musst es also nicht unbedingt händisch über eigen definierte Header lösen.

    ---

    Code:
    ByteArrayContent byteArray = new ByteArrayContent(bytes);
    byteArray.Headers.Add("file", [color=red]fileStream.Name[/color]);
    content.Add(byteArray);
    Sollte dort nicht einfach der Inhalt der Datei reingehören? Bei dir ist es aber nur der Name.

    EDIT: Außerdem sehe ich, dass du das teilweise über GET Parameter in der URL löst? Normal sollten doch alle Parameter an die in der API aufgeführte URL über POST kommen...? Jedenfalls wenn du den CURL-Befehl nachcoden und dich an die API in dem Link, den du gepostet hast, halten willst.

    Mfg,

    Kolazomai
     
  3. 3. März 2014
    AW: cURL request in C# Code umwandeln

    Zuerst solltest du mal sicherstellen, dass der Muplitpart/Form-Data Post funktioniert. Hier gibts ein passendes Snippet dazu: Multipart Form Post in C# - Brian Grinstead
    Wenn das passt sollte der Rest des Requests kein großes Problem darstellen. Zur Not einfach mit nem Network Logger schauen was fehlt.
     
  4. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.