I have this code:
var content = new ByteArrayContent(Encoding.ASCII.GetBytes(String.Concat("GET\t", _licencia, "\n")));
var recibido = await _client.PostAsync(fullUri, content);
var response = recibido.StatusCode;
this.IsOnline = response == HttpStatusCode.OK;
string contenido = await recibido.Content.ReadAsStringAsync();
if (this.IsOnline)
{
string data = contenido.TrimEnd();
List<string> transacciones = String.IsNullOrEmpty(data) ? null : data.Split('\n').ToList();
var guardadas = ProcessTransactions(transacciones);
if (guardadas != null)
{
StringBuilder sb = new StringBuilder(String.Concat("OK\t", _licencia, "\n"));
content = new ByteArrayContent(Encoding.ASCII.GetBytes(sb.ToString()));
recibido = await _client.PostAsync(fullUri, content);
Please see the first PostAsync call:
var content = new ByteArrayContent(Encoding.ASCII.GetBytes(String.Concat("GET\t", _licencia, "\n")));
var recibido = await _client.PostAsync(fullUri, content);
In this case, content length is only 34 bytes. So far, so good. Server receives the requirement correctly. But now see the second PostAsync call:
StringBuilder sb = new StringBuilder(String.Concat("OK\t", _licencia, "\n"));
content = new ByteArrayContent(Encoding.ASCII.GetBytes(sb.ToString()));
recibido = await _client.PostAsync(fullUri, content);
In this case, content length is 33 bytes. However, that call gets blocked and finally it throws Task Cancelled Exception. This is because of the timeout, which is defined by the HttpClient to be 1 minute 40 seconds.
Why the second call gets blocked? How can I solve it?
Thanks
Jaime
Related
I'm Using ADLS Gen2 Path-Update API to update file from ADLS which is already created.
As a body i can easily pass string which is working fine but the same with Stream is not working.
i'm reading local file data and trying to store it into stream and pass as a body but getting an error of Http request header is invalid
I have a quick test at my side, the following code which read local file as stream, then upload the stream to adls gen2. It works fine. Please try it at your side, and let me know if you have more issues.
static void Main(string[] args)
{
var auth = new AzureServiceTokenProvider();
const string url = "https://storage.azure.com/";
string token = auth.GetAccessTokenAsync(url).Result;
string requestUri = "https://xxx.dfs.core.windows.net/t11/b.txt?action=append&position=0";
var method = new HttpMethod("PATCH");
// read local file as stream
var mystream = File.OpenRead(#"D:\temp\1\test1.txt");
Console.WriteLine($"the stream length is: {mystream.Length}");
Console.WriteLine($"the position of the stream is: {mystream.Position}");
var stream_length = mystream.Length;
var request = new HttpRequestMessage(method, requestUri)
{
//Content = new StringContent(upload_string)
Content = new StreamContent(mystream)
};
// Add some defined headers
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
var i = request.Content.AsString().Length;
Console.WriteLine(request.Content.AsString());
var httpClient = new HttpClient();
var result = httpClient.SendAsync(request).Result;
Console.WriteLine("append result status code: "+ (int)result.StatusCode);
//for flush
string requestUri_2 = "https://xxx.dfs.core.windows.net/t11/b.txt?action=flush&position="+stream_length;
var request_2 = new HttpRequestMessage(method,requestUri_2);
using (HttpClient httpClient_2 = new HttpClient())
{
httpClient_2.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
HttpResponseMessage response = httpClient_2.SendAsync(request_2).Result;
Console.WriteLine("flush result status code: " + (int)response.StatusCode);
}
I have been trying to solve this bad request error. I am able to make the request call and Azure reports total calls correctly and also reports total errors.
I can not get this code example to work; however if I send this via their online console all is fine:
static async void MakeRequest()
{
string key1 = "YourKey"; // azure the one should work
string data = "https://pbs.twimg.com/profile_images/476054279438868480/vvv5YG0Q.jpeg";
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Request parameters
queryString["returnFaceId"] = "true";
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", key1);
Console.Beep();
var uri = "https://westus.api.cognitive.microsoft.com/face/v1.0/detect?" + queryString;
//string statusURL = HttpContext.Current.Request.Url.Host;
//console.WriteLine("Your Status URL address is :" + statusURL);
HttpResponseMessage response;
// Request body
// byte[] byteData = Encoding.UTF8.GetBytes("{url: https://pbs.twimg.com/profile_images/476054279438868480/vvv5YG0Q.jpeg}");
byte[] byteData = Encoding.UTF8.
GetBytes("{"+ "url"+":"+"https://pbs.twimg.com/profile_images/476054279438868480/vvv5YG0Q.jpeg" + "}");
using (var content = new ByteArrayContent(byteData))
{
content.Headers.ContentType =
new MediaTypeHeaderValue("application/json");
response = await client.PostAsync(uri, content);
}
HttpRequestMessage request =
new HttpRequestMessage(HttpMethod.Post, uri);
request.Content = new StringContent("{body}",
Encoding.UTF8,
"application/json");
//CONTENT-TYPE header
await client.SendAsync(request)
.ContinueWith(responseTask =>
{
Console.WriteLine("Response: {0}", responseTask.Result);
Console.WriteLine("-----------------------------------");
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("End of Post return from MS");
Console.WriteLine("Hit ENTER to exit...");
Console.ReadKey();
});
}// end of Make request
Your JSON is malformed. Your fields and non-scalar fields must be quoted. You also have some unnecessary code. Here's code that works:
static async void MakeRequest()
{
string key1 = "YourKey"; // azure the one should work
string imageUri = "https://pbs.twimg.com/profile_images/476054279438868480/vvv5YG0Q.jpeg";
var client = new HttpClient();
var queryString = HttpUtility.ParseQueryString(string.Empty);
// Request parameters
queryString["returnFaceId"] = "true";
// Request headers
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", key1);
var uri = "https://westus.api.cognitive.microsoft.com/face/v1.0/detect?" + queryString;
string body = "{\"url\":\"" + imageUri + "\"}";
using (var content = new StringContent(body, Encoding.UTF8, "application/json"))
{
await client.PostAsync(uri, content)
.ContinueWith(async responseTask =>
{
var responseBody = await responseTask.Result.Content.ReadAsStringAsync();
Console.WriteLine("Response: {0}", responseBody);
Console.WriteLine("-----------------------------------");
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("End of Post return from MS");
Console.WriteLine("Hit ENTER to exit...");
Console.ReadKey();
});
}
}// end of Make request
If you're using Visual Studio, I would recommend the NuGet package as this will handle much of the mundane details for you, including C# types for responses.
private void testbtn_Click(object sender, RoutedEventArgs e)
{
string url = "http://api.eve-central.com/api/evemon";
var request = WebRequest.Create(url);
request.ContentType = "application/json; charset=utf-8";
string text;
var response = (HttpWebResponse)request.GetResponse();
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
var data = JObject.Parse(text);
string finalized = data.ToString();
Im trying to parse a json response to get the string / int values out of ~6 fields, but for some reason or another the program hangs on:
text = sr.ReadToEnd();
if there the line:
var data = JObject.Parse(text);
is present. The function works properly if those lines are not present (although it just prints the raw json response with the markup tags). anybody know how to fix this?
I'm trying to post image as byte array.
I have converted image to byte as using following code now I want to post it to server.
WriteableBitmap btmMap = new WriteableBitmap(bi);
System.Windows.Media.Imaging.Extensions.SaveJpeg(btmMap, ms, 200, 200, 0, 100);
result = ms.ToArray();
How can I now perform the POST action?
I suggest MIME multipart as content type. It is the content type best suited for byte array, if you ask me. One way to implement this:
public static async Task<string> Upload(byte[] data, string fileName, string uri)
{
HttpClient client = new HttpClient();
HttpMultipartFormDataContent content = new HttpMultipartFormDataContent("Upload----" + DateTime.Now.ToString(System.Globalization.CultureInfo.InvariantCulture));
InMemoryRandomAccessStream contentStream = new InMemoryRandomAccessStream();
DataWriter dw = new DataWriter(contentStream);
dw.WriteBytes(data);
await dw.StoreAsync();
await dw.FlushAsync();
dw.DetachStream();
contentStream.Seek(0);
HttpStreamContent streamContent = new HttpStreamContent(contentStream);
content.Add(streamContent, "MIMEFile", fileName);
try
{
using (var message = await client.PostAsync(new Uri(uri), content))
{
if (message.StatusCode != HttpStatusCode.Ok)
{
return String.Format("ERROR ({0})",message.StatusCode);
}
var result = await message.Content.ReadAsStringAsync();
return result;
}
}
catch (Exception ex)
{
return String.Format("ERROR ({0})", ex.Message);
}
}
Try below code:
HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
var imageForm = new ByteArrayContent(result, 0, result.Count());
imagenForm.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");
form.Add(imagenForm, "image", "nameholder.jpg");
HttpResponseMessage response = await httpClient.PostAsync("URL_here", form);
response.EnsureSuccessStatusCode();
string result = response.Content.ReadAsStringAsync().Result;
httpClient.Dispose();
Hope this help's you to get idea about how to pass byte arry to POST into API call.
EDIT:
HttpClient httpClient = new HttpClient();
MultipartFormDataContent form = new MultipartFormDataContent();
form.Add(new StringContent(UserID), "UserID");
var imageForm = new ByteArrayContent(result, 0, result.Count());
imagenForm.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");
form.Add(imagenForm, "image", "nameholder.jpg");
HttpResponseMessage response = await httpClient.PostAsync("URL_here", form);
response.EnsureSuccessStatusCode();
string result = response.Content.ReadAsStringAsync().Result;
httpClient.Dispose();
I have followed the following post to do the upload in chunks to blob
How to track progress of async file upload to azure storage
But this is not working in windows store app or windows 8.1 app as there is no support for MemoryStream in win 8.1 app.
Anyhow I have modified the code in the above thread and come up with something like the following
CloudBlobClient myBlobClient = storageAccount.CreateCloudBlobClient();
var filePicker = new FileOpenPicker();
filePicker.FileTypeFilter.Add("*");
var file = await filePicker.PickSingleFileAsync();
string output = string.Empty;
var fileName = file.Name;
myBlobClient.SingleBlobUploadThresholdInBytes = 1024 * 1024;
CloudBlobContainer container = myBlobClient.GetContainerReference("files");
//container.CreateIfNotExists();
CloudBlockBlob myBlob = container.GetBlockBlobReference(fileName);
var blockSize = 256 * 1024;
myBlob.StreamWriteSizeInBytes = blockSize;
var fileProp = await file.GetBasicPropertiesAsync();
var bytesToUpload = fileProp.Size;
var fileSize = bytesToUpload;
if (bytesToUpload < Convert.ToUInt64(blockSize))
{
CancellationToken ca = new CancellationToken();
var ado = myBlob.UploadFromFileAsync(file).AsTask();
await
//Console.WriteLine(ado.Status); //Does Not Help Much
ado.ContinueWith(t =>
{
//Console.WriteLine("Status = " + t.Status);
//Console.WriteLine("It is over"); //this is working OK
});
}
else
{
List<string> blockIds = new List<string>();
int index = 1;
ulong startPosition = 0;
ulong bytesUploaded = 0;
do
{
var bytesToRead = Math.Min(Convert.ToUInt64(blockSize), bytesToUpload);
var blobContents = new byte[bytesToRead];
using (Stream fs = await file.OpenStreamForWriteAsync())
{
fs.Position = Convert.ToInt64(startPosition);
fs.Read(blobContents, 0, (int)bytesToRead);
//var iStream = fs.AsInputStream();
ManualResetEvent mre = new ManualResetEvent(false);
var blockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(index.ToString("d6")));
//Console.WriteLine("Now uploading block # " + index.ToString("d6"));
blockIds.Add(blockId);
var ado = myBlob.PutBlockAsync(blockId, fs.AsRandomAccessStream(), null).AsTask();
await ado.ContinueWith(t =>
{
bytesUploaded += bytesToRead;
bytesToUpload -= bytesToRead;
startPosition += bytesToRead;
index++;
double percentComplete = (double)bytesUploaded / (double)fileSize;
output += (percentComplete * 100).ToString() + ",";
// AppModel.TasksFormObj.SetProgress(percentComplete * 100);
// Console.WriteLine("Percent complete = " + percentComplete.ToString("P"));
mre.Set();
});
mre.WaitOne();
}
}
while (bytesToUpload > 0);
//Console.WriteLine("Now committing block list");
var pbl = myBlob.PutBlockListAsync(blockIds).AsTask();
pbl.ContinueWith(t =>
{
//Console.WriteLine("Blob uploaded completely.");
});
}
}
The above code will save the file in blob and the progress is also fine but the saved file in blob is always in 0 bytes . After debugging I found there was an error thrown after var ado = myBlob.PutBlockAsync(blockId, fs.AsRandomAccessStream(), null).AsTask(); for the last blob transfer as
<?xml version="1.0" encoding="utf-16"?>
<!--An exception has occurred. For more information please deserialize this message via RequestResult.TranslateFromExceptionMessage.-->
<RequestResult>
<HTTPStatusCode>400</HTTPStatusCode>
<HttpStatusMessage>The value for one of the HTTP headers is not in the correct format.</HttpStatusMessage>
<TargetLocation>Primary</TargetLocation>
<ServiceRequestID>13633308-0001-0031-060b-7249ea000000</ServiceRequestID>
<ContentMd5 />
<Etag />
<RequestDate>Sun, 28 Feb 2016 10:31:44 GMT</RequestDate>
<StartTime>Sun, 28 Feb 2016 09:31:43 GMT</StartTime>
<EndTime>Sun, 28 Feb 2016 09:31:44 GMT</EndTime>
<Error>
<Code>InvalidHeaderValue</Code>
<Message>The value for one of the HTTP headers is not in the correct format.
RequestId:13633308-0001-0031-060b-7249ea000000
Time:2016-02-28T09:34:18.3545085Z</Message>
<HeaderName>Content-Length</HeaderName>
<HeaderValue>0</HeaderValue>
</Error>
<ExceptionInfo>
<Type>StorageException</Type>
<HResult>-2147467259</HResult>
<Message>The value for one of the HTTP headers is not in the correct format.</Message>
<Source>Microsoft.WindowsAzure.Storage</Source>
<StackTrace> at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.<ExecuteAsyncInternal>d__c`1.MoveNext()</StackTrace>
</ExceptionInfo>
</RequestResult>
Then on the last commit the error thrown after myBlob.PutBlockListAsync(blockIds) as The specified block list is invalid
So please someone help me to to figure out where I am doing wrong or what is the possible solution to make it work 100%.
Use AsTask() like this.
CancellationTokenSource _cts;
_cts = new CancellationTokenSource();//<--In Constructor
var progress = new Progress<double>(TranscodeProgress);
await var ado = myBlob.UploadFromFileAsync(file).AsTask(_cts.Token, progress);