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