0

I'm trying to post a file to my WebAPI using

$ curl -F "appName=SomeApp" -F "version=1.0.0.0" -T C:/path/to/a/file.zip http://localhost/api/AppRepo/AddApp

By following this answer https://stackoverflow.com/a/10327789/1421847, I've been able to accept a file with option -F "image=@C:/path/to/a/file.zip" and also read the appName and version parameters. However using cURL in VSTS build task https://github.com/Microsoft/vso-agent-tasks/tree/master/Tasks/cURLUploader I'll have to accept a request using the -T option.

So far, I've found that it does an http PUT request and the content is not MimeMultipart.

Community
  • 1
  • 1
Eivind Gussiås Løkseth
  • 1,862
  • 2
  • 21
  • 35

1 Answers1

0

I found that using the -T option prevents me from sending additional parameters as HTTP content, so instead I added -H "X-App-Name: MyAppName" and -H "X-App-Version: 1.0.0.0" in the cURL call to get those values in as HTTP headers instead.

My WebAPI method handling the request now looks as follows:

public async Task<HttpResponseMessage> PutApp()
{
    const string UnexpectedContentOrHeadersMessage = "Expected a zip-file as content and http headers X-App-Name and X-App-Version.";
    if (Request.Content.IsFormData() || Request.Content.IsHttpRequestMessageContent() || Request.Content.IsMimeMultipartContent())
        throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType, UnexpectedContentOrHeadersMessage));

    string appName;
    IEnumerable<string> appNameValues;
    if (Request.Headers.TryGetValues("X-App-Name", out appNameValues))
        appName = appNameValues.First();
    else
        throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType, UnexpectedContentOrHeadersMessage));

    Version version;
    IEnumerable<string> appVersionValues;
    if (Request.Headers.TryGetValues("X-App-Version", out appVersionValues))
        version = new Version(appVersionValues.First());
    else
        throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType, UnexpectedContentOrHeadersMessage));

    return new HttpResponseMessage(HttpStatusCode.OK);
}

To write the content as binary data, I simply do some standard IO stuff:

var bytes = await httpContent.ReadAsByteArrayAsync();
Guid fileId = Guid.NewGuid();
FileInfo uploadFile = new FileInfo(Path.Combine(Server.MapPath("~/App_Data"), fileId.ToString()));

using (FileStream fileStream = uploadFile.OpenWrite())
{
    await fileStream.WriteAsync(bytes, 0, bytes.Length);
}

This is the complete cURL call: $ curl --ntlm --user <user>:<password> -H "X-App-Name: <app-name>" -H "X-App-Version: <app-version>" -T c:/path/to/a/file.zip http://localhost/api/AppRepository/PutApp

Eivind Gussiås Løkseth
  • 1,862
  • 2
  • 21
  • 35