I am new to C# and trying to download a file from azure git repo. The response status is success but not downloading the file to local drive. I m passing all parameters correctly.
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", personalaccesstoken))));
using (HttpResponseMessage response = client.GetAsync(
$"https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/items?path={path}&download={download}&versionDescriptor.versionType={versionDescriptor_versionType}&versionDescriptor.version={versionDescriptor_version}&api-version=7.0").Result)
{
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
}
and the output i am getting as below.
{
"objectId": "34e9cd84219e51533b19b3a70121e73b612c0eca",
"gitObjectType": "blob",
"commitId": "1916fd237ce345505a0cdbb285ce0ba71a64691b",
"path": "/Backend/DATA/Document_AA083_A100001.xml",
"url": "https://dev.azure.com/xxxx-xxx-xxx/00e7c28c-efde-450e-91a1-133b7f2a228c/_apis/git/repositories/062ef079-ab27-4ed9-ba91-aaa0678d89b5/items?path=%2FBackend%2FDATA%2FDocument_AA083_A100001.xml&versionType=Branch&version=tcs00107%2FGIT_Tool&versionOptions=None",
"_links": {
"self": {
"href": "https://dev.azure.com/xxxx-xxx-xxx/00e7c28c-efde-450e-91a1-133b7f2a228c/_apis/git/repositories/062ef079-ab27-4ed9-ba91-aaa0678d89b5/items?path=%2FBackend%2FDATA%2FDocument_AA083_A100001.xml&versionType=Branch&version=tcs00107%2FGIT_Tool&versionOptions=None"
},
"repository": {
"href": "https://dev.azure.com/xxxx-xxx-xxx/00e7c28c-efde-450e-91a1-133b7f2a228c/_apis/git/repositories/062ef079-ab27-4ed9-ba91-aaa0678d89b5"
},
"blob": {
"href": "https://dev.azure.com/xxxx-xxx-xxx/00e7c28c-efde-450e-91a1-133b7f2a228c/_apis/git/repositories/062ef079-ab27-4ed9-ba91-aaa0678d89b5/blobs/34e9cd84219e51533b19b3a70121e73b612c0eca"
}
}
}
It would be really helpful if anyone Could help me to resolve this issue .
Much appreciated for your help.
The problem is the JSON response you are getting, consists of metadata about the file. You have to use the "url" and perform another get request using "HttpClient.GetByteArrayAsync()". This gets the file as a byte array, which can then be written to your local drive using "File.WriteAllBytes(string, byte[])".
using (HttpClient client = new HttpClient())
{
//.. your existing code
var responseBody = await response.Content.ReadAsStringAsync();
dynamic jsonData = JsonConvert.DeserializeObject(responseBody);
var blobUrl = jsonData._links.blob.href;
byte[] fileBytes = await client.GetByteArrayAsync(blobUrl);
File.WriteAllBytes("path/to/local/file", fileBytes);
}
Change the path to where you want the file saved, and be aware of any permissions/restrictions to the filepath.
Related
I was trying to download work item attachment from devops using the REST API. The file is downloading, but file name and extension are not correct and I'm unable to open after downloading the file.
var personalaccesstoken = "";
var DeserializedClass = new List<Responcejson>();
string bseurl = "https://xxx/_apis/wit/attachments/xxxx-0cdb-4f53-9785-55d642d603e7?fileName=abc.png&download=true&api-version=5.0";
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", personalaccesstoken))));
using (HttpResponseMessage response = await client.GetAsync(bseurl))
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
//JObject data = JObject.Parse(responseBody);
return responseBody;
}
}
}
catch (Exception ex)
{
return ex.ToString();
}
but this downloads the file as "Devops" with no filename and extension....
Thanks in advance
When executing the Azure DevOps REST API "Downloads an attachment", you can use the Media Types "application/octet-stream" or "application/zip". See here.
I noticed this in your code,
string responseBody = await response.Content.ReadAsStringAsync();
If the attachment is image, this may cause issues.
In addition, there is the corresponding client API you can directly use in your C# code.
See "WorkItemTrackingHttpClientBase.GetAttachmentContentAsync Method".
I'm trying to make a simple request to the Basecamp API, I'm following the instructions provided adding in a sample user agent and my credentials yet I keep getting a 403 Forbidden response back.
My credentials are definitely correct so is it a case of my request/credentials being set incorrectly?
This is what I have (removed personal info):
var httpClient = new HttpClient();
var content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("User-Agent", "MyApp [EMAIL ADDRESS]") });
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "[USERNAME]", "[PASSWORD]"))));
var response = await httpClient.PostAsync("https://basecamp.com/[USER ID]/api/v1/projects.json", content);
var responseContent = response.Content;
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
Console.WriteLine(await reader.ReadToEndAsync());
}
A quick look over their documentation seems to indicate that the projects.json endpoint accepts the following in the body of the POST:
{
"name": "This is my new project!",
"description": "It's going to run real smooth"
}
You're sending the User-Agent as the POST body. I'd suggest you change your code as follows:
var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "[USERNAME]", "[PASSWORD]")));
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("User-Agent", "MyApp [EMAIL ADDRESS]");
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
var response = await httpClient.PostAsJsonAsync(
"https://basecamp.com/[USER ID]/api/v1/projects.json",
new {
name = "My Project",
description = "My Project Description"
});
var responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseContent);
}
This posts the payload as specified in the docs and sets your user agent in the headers as it should be.
I have been trying to make a call to Cognitive Services from within Azure Functions without much luck. I have a Blob Triggered Function, which starts when an object is added to the blob. I wanted to output something to another blob container within the same Function.
I was able to achieve this in the following way
Created a Function app (Blob Triggered) with the following bindings:
"bindings": [
{
"name": "myBlob",
"type": "blobTrigger",
"direction": "in",
"path": "originals/{name}",
"connection": "AzureWebJobsStorage"
},
{
"type": "blob",
"name": "outputBlob",
"path": "extracted/processed-{name}.json",
"connection": "AzureWebJobsStorage",
"direction": "out"
}
], "disabled": false
Used the following code:
#r "Newtonsoft.Json"
using System;
using System.Text;
using System.Net.Http;
using System.Net.Http.Headers;
using Newtonsoft.Json;
public static async Task Run(Stream myBlob, Stream outputBlob, TraceWriter log)
{
string subscriptionKey = "YOUR KEY HERE";
string uriBase = "https://westcentralus.api.cognitive.microsoft.com/vision/v1.0/recognizeText";
int ID = 0;
String outputJSON = "json string to be written onto blob";
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
string requestParameters = "handwriting=true";
string uri = uriBase + "?" + requestParameters;
HttpResponseMessage response = null;
string operationLocation = null;
HttpContent content = new StreamContent(myBlob);
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response = await client.PostAsync(uri, content);
if (response.IsSuccessStatusCode)
operationLocation = response.Headers.GetValues("Operation-Location").FirstOrDefault();
else
{
log.Info("\nError:\n");
log.Info((await response.Content.ReadAsStringAsync()));
return;
}
string contentString;
...
...
System.Threading.Thread.Sleep(1000);
response = await client.GetAsync(operationLocation);
contentString = await response.Content.ReadAsStringAsync();
RootObject jObj = JsonConvert.DeserializeObject<RootObject>(contentString);
log.Info(outputJSON); // at this point outputjson has the info needed to write onto the new blob
byte[] data = Encoding.ASCII.GetBytes(outputJSON);
outputBlob.Write(data,0,data.Length);
}
I hope this helps. Cheers! :)
I am working on how to upload a media file using the VoiceBase API. I tried using HttpClient ( with MultipartFormDataContent and FormUrlEncodedContent), RestClient , WebClient and WebRequest. But it didn't worked.
Following is the code I tried:
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "xxxx");
MultipartFormDataContent form = new MultipartFormDataContent();
form.Add(new StringContent("http:/xx.mp3"), "media", "testFile.mp3");
HttpResponseMessage response = await client.PostAsync("https://apis.voicebase.com/v2-beta/media", form);
HttpContent responseContent = response.Content;
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
var a = reader.ReadToEndAsync();
return response;
}
API returns this error:
"status": 400,
"errors":
{
"error": "We have identified 1 error in your request: (1) Your upload was rejected because the media file not be successfully parsed (80 bytes )."
},
"reference": "3D00BCA8:A910_0A40E32A:01BB_5949122A_69009:79C6"
}
Edit
I have also tried with binary data:
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "xxxx");
MultipartFormDataContent form = new MultipartFormDataContent();
form.Add(new ByteArrayContent(File.ReadAllBytes(#"C:\Users\xxxx.mp3")), "media", "xxxx.mp3");
HttpResponseMessage response = await client.PostAsync("https://apis.voicebase.com/v2-beta/media", form);
HttpContent responseContent = response.Content;
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
var a = reader.ReadToEndAsync();
return response;
}
With binary data I was getting following error:
{
"status": 400,
"errors":
{
"error": "We have identified 1 error in your request: (1) We could not download the URL"
}
,
"reference": "3D00BCA8:DFF5_0A40E32A:01BB_59491448_6F33E:79C6"
}
I needed to do this today so I've made an attempt to wrap up my work on the V3 API in a nuget package here:
https://www.nuget.org/packages/VoiceBaseV3/
When I get the time I'll get it on GitHub too
The first parameter of your form.Add(...) needs to be a data stream of the contents of the actual file, not a string. To do this you can make a new memory stream like this: new MemoryStream(File.ReadAllBytes(localfilePath))
Try this:
var content = new StreamContent(new FileStream(#"C:\Users\xxxx.mp3", FileMode.Open));
content.Headers.ContentType = new MediaTypeHeaderValue("audio/mp3");
MultipartFormDataContent form = new MultipartFormDataContent();
form.Add(content, "media", "xxxx.mp3");
If you use V3, you can generate the client code with Swagger on the language of your preference
https://voicebase.readthedocs.io/en/v3/how-to-guides/swagger-codegen.html
I'm trying to make a simple request to the Basecamp API, I'm following the instructions provided adding in a sample user agent and my credentials yet I keep getting a 403 Forbidden response back.
My credentials are definitely correct so is it a case of my request/credentials being set incorrectly?
This is what I have (removed personal info):
var httpClient = new HttpClient();
var content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("User-Agent", "MyApp [EMAIL ADDRESS]") });
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "[USERNAME]", "[PASSWORD]"))));
var response = await httpClient.PostAsync("https://basecamp.com/[USER ID]/api/v1/projects.json", content);
var responseContent = response.Content;
using (var reader = new StreamReader(await responseContent.ReadAsStreamAsync()))
{
Console.WriteLine(await reader.ReadToEndAsync());
}
A quick look over their documentation seems to indicate that the projects.json endpoint accepts the following in the body of the POST:
{
"name": "This is my new project!",
"description": "It's going to run real smooth"
}
You're sending the User-Agent as the POST body. I'd suggest you change your code as follows:
var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "[USERNAME]", "[PASSWORD]")));
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("User-Agent", "MyApp [EMAIL ADDRESS]");
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
var response = await httpClient.PostAsJsonAsync(
"https://basecamp.com/[USER ID]/api/v1/projects.json",
new {
name = "My Project",
description = "My Project Description"
});
var responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseContent);
}
This posts the payload as specified in the docs and sets your user agent in the headers as it should be.