I have image in the form of byte[] data and code to pass byte data to get response from client. I need help in putting them together
I tried to use the code where I have my byte data but the async operations created a lot of confusion
"data" contains the byte[] data
private async void InitializeVideoFeedModule()
{
//Must in UI thread
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
//Raw data and decoded data listener
if (videoParser == null)
{
videoParser = new DJIVideoParser.Parser();
videoParser.Initialize( delegate (byte[] data)
{
return DJISDKManager.Instance.VideoFeeder.ParseAssitantDecodingInfo(0, data);
});
}
}
}
code to pass byte data and get response
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Prediction-Key", "XXXXX");
// Prediction URL - replace this example URL with valid Prediction URL.
string sequenceURL = "https://abc/dcr/xyz";
HttpResponseMessage response;
using (var content = new ByteArrayContent(data))
{
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response = await client.PostAsync(sequenceURL, content);
var output = await response.Content.ReadAsStringAsync();
Console.WriteLine(output);
JObject json = JObject.Parse(output);
}
The delegate object and async operations are causing conflicts when I use them together.
Related
In the following code, I can send a POST request for the webserver and get a response:
private static readonly HttpClient client = new HttpClient();
public async static Task<int> User(string email, string password)
{
email = email.ToLower();
string theEmail = Cryptor.Encrypt(email);
string thePass = Cryptor.Encrypt(password);
try
{
var values = new Dictionary<string, string>
{
{ "email", theEmail },
{ "password", thePass }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("https://url...", content);
var responseString = await response.Content.ReadAsStringAsync();
Globals.USER = JsonConvert.DeserializeObject<UserObject>(responseString);
return 1;
}
catch (Exception)
{
return 3;
}
}
Is there a way to get a file sending a POST request and then save this file in a specific folder in the user's computer?
(What would be the PHP code to return the file after receiving the user's credentials and how would I get this file in the C# code?)
For example:
<?php
if($_SERVER['REQUEST_METHOD'] == "POST"){
$email = $_POST['email'];
$password = $_POST['password'];
// Validate user
// .
// .
// .
// Until here it's ok
// Now what would be the code to return the file?
// For example, a file from the following path: "user-folder/docs/image.png"
}else{
echo 'error';
die;
}
And in the WPF App, in C# usually I would read the response like this:
var response = await client.PostAsync("https://url...", content);
var responseString = await response.Content.ReadAsStringAsync();
But how would it be to get the file back?
Sending files is generally done by transferring the content as binary data. If you don't explicitly send text data, using HttpClient.ReadAsString is useless. Either read the response content as byte array or as stream.
Sending the file using the readfile() function:
$file = 'user-folder/docs/image.png';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' .filesize($file));
readfile($file);
exit;
There are alternatives e.g., using cURL etc.
To request and save the file on your C# client you can handle the response content directly as Stream or byte array:
var response = await httpClient.PostAsync("https://url...", content);
var destinationFilePath = "image.png";
await using var destinationStream = File.Create(destinationFilePath);
// Handle the response directly as Stream
await using Stream sourceStream = await response.Content.ReadAsStreamAsync();
await sourceStream.CopyToAsync(destinationStream);
// Alternatively, create the Stream manually
// or write the byte array directly to the file
byte[] sourceData = await response.Content.ReadAsByteArrayAsync();
await destinationStream.WriteAsync(sourceData);
So I've looked around for an answer for this but nothing I've found even comes close to solving it.
I'm trying to set up a Post method on my Web API but no matter what I do it just gives me an internal server error.
I've tried adding [FromBody] (it's a simple type).
HttpClient client {get;set;}
public APICall()
{
client = new HttpClient
{
BaseAddress = new Uri("http://localhost:1472/api/")
};
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-protobuf"));
}
public void PostTimeTaken(long timeTaken)
{
var response = client.PostAsJsonAsync("Logging", timeTaken).Result;
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.ReasonPhrase);
}
}
and then my controller action looks like this:
public void Post([FromBody] long timeTaken)
{
_api.DataBuilder.NumberOfAPICalls += 1;
_api.DataBuilder.ResponseTimes.Add(timeTaken);
}
I get no error message that could actually explain what's going on, just "Internal server error"
------SOLVED-------
Just in case anyone stumbles across this looking for the same answer, the issue was I was sending the data to the server in an incorrect format, it needed to be ProtoBuf serialised first, code snippet for anyone it might help:
public void PostToAPI(int ThingToSend)
{
using (var stream = new MemoryStream())
{
// serialize to stream
Serializer.Serialize(stream, ThingToSend);
stream.Seek(0, SeekOrigin.Begin);
// send data via HTTP
StreamContent streamContent = new StreamContent(stream);
streamContent.Headers.Add("Content-Type", "application/x-protobuf");
var response = client.PostAsync("Logging", streamContent);
Console.WriteLine(response.Result.IsSuccessStatusCode);
}
}
using (var client = new HttpClient())
{
string url = "http://localhost:7936";
client.BaseAddress = new Uri(url);
var jsonString = JsonConvert.SerializeObject(contentValue);
var content = new StringContent(jsonString, Encoding.UTF8, "application/json");
var result = await client.PostAsync("/Api/Logger/PostActionLog", content);
string resultContent = await result.Content.ReadAsStringAsync();
}
Have you tried to convert
long timeTaken to A model like;
public class TimeModel {
public long TimeTaken {get;set;}
}
public void Post([FromBody] TimeModel time){
// Do Stuff
}
Here the code of creating a simple server
baseUrl = "http://localhost:1472/"; // change based on your domain setting
using (WebApp.Start<StartUp>(url: baseUrl))
{
HttpClient client = new HttpClient();
var resp = client.GetAsync(baseUrl).Result;
}
Here some changes in your code
var requestData = new List<KeyValuePair<string, string>> // here
{
new KeyValuePair<string, string>( "Logging",timeTaken),
};
Console.WriteLine("request data : " + requestData);
FormUrlEncodedContent requestBody = newFormUrlEncodedContent(requestData);
var request = await client.PostAsync("here pass another server API", requestBody);
var response = await request.Content.ReadAsStringAsync();
Console.WriteLine("link response : " + response);
Pls add your controller
[HttpPost] // OWIN - Open Web Interface for .NET
public HttpResponseMessage Post([FromBody] long timeTaken)
{
_api.DataBuilder.NumberOfAPICalls += 1;
_api.DataBuilder.ResponseTimes.Add(timeTaken);
return Request.CreateResponse(HttpStatusCode.OK); //Using Post Method
}
I am trying to write a code about reading a list of images and get the information from it using Cognitive Service MVC.NET.
I wrote this code:
public async Task<ActionResult> Index()
{
List<string> list = await ReadImages();
return View(list);
}
private async Task<List<string>> ReadImages()
{
List<string> list = new List<string>();
string[] photoEntries = Directory.GetFiles(_photoFolder);
foreach (string photo in photoEntries)
{
list.Add(await GetCaptionAsync(photo));
}
return list;
}
private async Task<string> GetCaptionAsync(string photo)
{
using (var client = new HttpClient())
{
var queryString = HttpUtility.ParseQueryString(string.Empty);
//setup HttpClient
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", _apiKey);
queryString["visualFeatures"] = "Categories";
queryString["details"] = "Celebrities";
queryString["language"] = "en";
var uri = "https://westus.api.cognitive.microsoft.com/vision/v1.0/analyze?" + queryString;
HttpResponseMessage response;
byte[] byteData = Encoding.UTF8.GetBytes(photo);
using (var content = new ByteArrayContent(byteData))
{
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response = await client.PostAsync(uri, content);
}
return response.Content.ToString();
}
}
the View is:
#model List<string>
#foreach (var item in Model)
{
#item
}
I am receiving an Error: 400 Bad request in the line:
response = await client.PostAsync(uri, content);
I do not know what is wrong in this code, anybody please can help me and explain a little about the problem?
thank you
If you're using c#, you'll find the official client SDK a time-saver, available also in NuGet. In addition to ready-made code to call the service, it will give you concrete types so you don't have to parse the response JSON yourself.
Anyway, your code is mostly correct, but the payload needs to be the file content in binary. So you'll want instead:
byte[] byteData = File.ReadAllBytes(photo);
Also note that you'll want to wait for the response content like this:
return await response.Content.ReadAsStringAsync();
I am doing HTTP get request using HttpClient in C# console app . I am not getting expected response with one get request.
Get Request is like
http://example.com/xyz/SearchProduct?productNo=11210&1d6rstc9xc=5jyi27htzk
I am getting some vague response but when i do same get request with fiddler it is giving expected response.
How can I get expected response from httpClient.GetAsync(url)?
code is :-
var httpClient = new HttpClient();
var url = "http://example.com/xyz/SearchProduct?productNo=11210&1d6rstc9xc=5jyi27htzk";
HttpResponseMessage response1 = await httpClient.GetAsync(url);
if (response1.IsSuccessStatusCode)
{
HttpContent stream = response1.Content;
Task<string> data = stream.ReadAsStringAsync();
}
You should read as string that way:
string result = await stream.ReadAsStringAsync();
instead of that:
Task<string> data = stream.ReadAsStringAsync();
Here full code example and another example
This is a full method using async/await approach.
private static async Task<string> GetRequestContentAsString(string url)
{
var data = string.Empty;
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var stream = response.Content;
data = await stream.ReadAsStringAsync();
}
}
return data;
}
This method is called this way:
var content = await GetRequestContentAsString("http://www.bing.com");
I'm trying to send some images + some meta data to a server by HTTP post from a windows store app but get stuck when trying to actually include the data in the post. It cannot be done the way you would accomplish this in a windows forms app or similar due to the changes to the store app API.
I get the error.
cannot convert source type byte[] to target type System.Net.Http.httpContent
now this is obviously because it's 2 different types that can't be implicitly casted, but it's basically what I'm looking to be able to do. How do I make get my byte array data into the httpContent type so I can include it in the following call
httpClient.PostAsync(Uri uri,HttpContent content);
here's my full upload method:
async private Task UploadPhotos(List<Photo> photoCollection, string recipient, string format)
{
PhotoDataGroupDTO photoGroupDTO = PhotoSessionMapper.Map(photoCollection);
try
{
var client = new HttpClient();
client.MaxResponseContentBufferSize = 256000;
client.DefaultRequestHeaders.Add("Upload", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
// POST action_begin
const string actionBeginUri = "http://localhost:51139/PhotoService.axd?action=Begin";
HttpResponseMessage response = await client.GetAsync(actionBeginUri);
response.EnsureSuccessStatusCode();
string responseBodyAsText = await response.Content.ReadAsStringAsync();
string id = responseBodyAsText;
////
// POST action_upload
Uri actionUploadUri = new Uri("http://localhost:51139/PhotoService.axd?action=Upload&brand={0}&id={1}&name={2}.jpg");
var metaData = new Dictionary<string, string>()
{
{"Id", id},
{"Brand", "M3rror"}, //TODO: Denne tekst skal komme fra en konfigurationsfil.
{"Format", format},
{"Recipient", recipient}
};
string stringData = "";
foreach (string key in metaData.Keys)
{
string value;
metaData.TryGetValue(key, out value);
stringData += key + "=" + value + ",";
}
UTF8Encoding encoding = new UTF8Encoding();
byte[] byteData = encoding.GetBytes(stringData);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, actionUploadUri);
// send meta data
// TODO get byte data in as content
HttpContent metaDataContent = byteData;
HttpResponseMessage actionUploadResponse = await client.PostAsync(actionUploadUri, metaDataContent);
actionUploadResponse.EnsureSuccessStatusCode();
responseBodyAsText = await actionUploadResponse.Content.ReadAsStringAsync();
// send photos
// TODO get byte data in as content
foreach (byte[] imageData in photoGroupDTO.PhotosData)
{
HttpContent imageContent = imageData;
actionUploadResponse = await client.PostAsync(actionUploadUri, imageContent);
actionUploadResponse.EnsureSuccessStatusCode();
responseBodyAsText = await actionUploadResponse.Content.ReadAsStringAsync();
}
////
// POST action_complete
const string actionCompleteUri = "http://localhost:51139/PhotoService.axd?action=Complete";
HttpResponseMessage actionCompleteResponse = await client.GetAsync(actionCompleteUri);
actionCompleteResponse.EnsureSuccessStatusCode();
responseBodyAsText = await actionCompleteResponse.Content.ReadAsStringAsync();
////
}
catch (HttpRequestException e)
{
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
}
It will be more straightforward to use System.Net.Http.ByteArrayContent. E.g:
// Converting byte[] into System.Net.Http.HttpContent.
byte[] data = new byte[] { 1, 2, 3, 4, 5};
ByteArrayContent byteContent = new ByteArrayContent(data);
HttpResponseMessage reponse = await client.PostAsync(uri, byteContent);
For text only with an specific text encoding use:
// Convert string into System.Net.Http.HttpContent using UTF-8 encoding.
StringContent stringContent = new StringContent(
"blah blah",
System.Text.Encoding.UTF8);
HttpResponseMessage reponse = await client.PostAsync(uri, stringContent);
Or as you mentioned above, for text and images using multipart/form-data:
// Send binary data and string data in a single request.
MultipartFormDataContent multipartContent = new MultipartFormDataContent();
multipartContent.Add(byteContent);
multipartContent.Add(stringContent);
HttpResponseMessage reponse = await client.PostAsync(uri, multipartContent);
You need to wrap the byte array in an HttpContent type.
If you are using System,Net.Http.HttpClient:
HttpContent metaDataContent = new ByteArrayContent(byteData);
If you are using the preferred Windows.Web.Http.HttpClient:
Stream stream = new MemoryStream(byteData);
HttpContent metaDataContent = new HttpStreamContent(stream.AsInputStream());
The concept you are looking for is called Serialization. Serialization means preparing your data (which could be heterogeneous and without a predefined strucutre) for storage or transmission. Then, when you need to use the data again, you do the opposite operation, deserialization, and get back the original data structure. The link above shows a few methods on how this could be done in C#.