Reputation: 45911
I'm developing an ASP.NET Web Api 2 with C# and .NET Framework 4.7.
I'm trying to upload a file to the web api using a HttpClient instance.
I have added this to Web.Config:
<httpRuntime targetFramework="4.7" maxRequestLength="1048576" />
[ ... ]
<location path="ProductionOrderApi">
<system.web>
<httpRuntime executionTimeout="120" maxRequestLength="81920" />
</system.web>
</location>
[ ... ]
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="1073741824" />
</requestFiltering>
</security>
This is the web api method:
[HttpPost]
[Route("api/ProductionOrder/{productionOrderName}/Processed")]
public HttpResponseMessage UploadProductionOrderProcessed(
string productionOrderName,
byte[] jsonData)
{
HttpResponseMessage response = null;
try
{
Data.ProductionOrder po = repository
.SearchFor(p => string.Equals(p.Name, productionOrderName) &&
p.Phase == (byte)Phase.Processed)
.FirstOrDefault();
if (po == null)
response = Request.CreateResponse(HttpStatusCode.InternalServerError);
else
{
string json = Encoding.ASCII.GetString(jsonData);
StoredProcedureErrors error =
StoredProcedures.LoadProcessedBatch(connectionString, json);
if (error == StoredProcedureErrors.NoError)
response = Request.CreateResponse(HttpStatusCode.Created);
else
{
response = Request.CreateResponse(HttpStatusCode.InternalServerError);
exceptionLogger.LogMessage(
this.GetType().Name,
System.Reflection.MethodBase.GetCurrentMethod().Name,
"Database error: " + error);
}
}
}
catch (Exception ex)
{
exceptionLogger.LogCompleteException(
this.GetType().Name,
System.Reflection.MethodBase.GetCurrentMethod().Name,
ex);
response = Request.CreateResponse(HttpStatusCode.InternalServerError);
}
return response;
}
This is client to make the call:
public bool UploadProcessedBatch(string productionOrderName, byte[] jsonData)
{
string completeUri = string.Format(UploadProcessedBatchUri, productionOrderName);
return Post<byte[]>(completeUri, jsonData);
}
protected bool Post<T>(string completeUri, T dataToPost)
{
if (EqualityComparer<T>.Default.Equals(dataToPost, default(T)))
throw new ArgumentNullException("dataToPost");
bool result = false;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_webApiHost);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpContent content = new StringContent(JsonConvert.SerializeObject(dataToPost), Encoding.UTF8, "application/json");
Task<HttpResponseMessage> response = client.PostAsync(completeUri, content);
HttpResponseMessage message = response.Result;
result = (message.StatusCode == HttpStatusCode.Created);
LatestStatusCode = message.StatusCode;
ReasonPhrase = message.ReasonPhrase;
}
return result;
}
If I make a call with PostMan without posting any jsonData
it receives the call, but when I make a call with any jsonData
it doesn't call it (I have a breakpoint at first line in Web Api method): I get an exception saying "Cancelled task" with anything else useful.
The file I'm trying to upload it is big (more than 7 MB).
Any idea about what is it happening?
I think the problem is how I sending the data. All the examples that I have found are about sending the data with a Html form but I haven't found anything about how to send it with a HttpClient.
Upvotes: 1
Views: 3148
Reputation: 671
Edit:
So since Web Api 2.1 it is possible to use BSON, a "JSON-like" Format, which is able to send binary formatted data. In the linked Article you'll even find an example using HttpClient.
Before the Introduction of BSON a common way around the limitation of JSON has been to encode the binary as base64.
Orig:
The short of it is you can't simply send a byte[] as a Json Property.
Possible work-arounds are:
Maybe someone else has something to add to that list.
Cheers,
Upvotes: 1