问题
Need to store the image from a private git repository to a blob using C#. Tried with below code but getting 404 errors.
I am using the below code from C# example of downloading GitHub private repo programmatically
var githubToken = "[token]";
var url =
"https://github.com/[username]/[repository]/archive/[sha1|tag].zip";
var path = @"[local path]";
using (var client = new System.Net.Http.HttpClient())
{
var credentials = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}:", githubToken);
credentials = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(credentials));
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", credentials);
var contents = client.GetByteArrayAsync(url).Result;
System.IO.File.WriteAllBytes(path, contents);
}
Note: Able to fetch from the public repository
回答1:
According to the message you provide, you use the wrong url to download. Regarding how to get the download url, please refer to the following steps:
- Use the following url to get the download url
Method: GET
URL: https://api.github.com/repos/:owner/:repo/contents/:path?ref:<The name of the commit/branch/tag>
Header:
Authorization: token <personal access token>
The repose body will tell you the download url For example :
- Download file
For more details, please refer to https://developer.github.com/v3/repos/contents/#get-contents.
回答2:
How to fix :
The URL is changed to
GET /repos/:owner/:repo/:archive_format/:ref
. See https://developer.github.com/v3/repos/contents/#get-archive-linkFor private repositories, these links are temporary and expire after five minutes.
GET /repos/:owner/:repo/:archive_format/:ref
You should not pass the credentials using basic authentication. Instead, you should create a token by following the official docs. see https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line
- Finally, you need pass an extra
User-Agent
header. It is required by GitHub API. See https://developer.github.com/v3/#user-agent-required :All API requests MUST include a valid User-Agent header.
Demo
public class GitHubRepoApi{
public string EndPoint {get;} = "https://api.github.com/repos";
public async Task DownloadArchieveAsync(string saveAs, string owner, string token, string repo,string @ref="master",string format="zipball")
{
var url = this.GetArchieveUrl(owner, repo, @ref, format);
var req = this.BuildRequestMessage(url,token);
using( var httpClient = new HttpClient()){
var resp = await httpClient.SendAsync(req);
if(resp.StatusCode != System.Net.HttpStatusCode.OK){
throw new Exception($"error happens when downloading the {req.RequestUri}, statusCode={resp.StatusCode}");
}
using(var fs = File.OpenWrite(saveAs) ){
await resp.Content.CopyToAsync(fs);
}
}
}
private string GetArchieveUrl(string owner, string repo, string @ref = "master", string format="zipball")
{
return $"{this.EndPoint}/{owner}/{repo}/{format}/{@ref}"; // See https://developer.github.com/v3/repos/contents/#get-archive-link
}
private HttpRequestMessage BuildRequestMessage(string url, string token)
{
var uriBuilder = new UriBuilder(url);
uriBuilder.Query = $"access_token={token}"; // See https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line
var req = new HttpRequestMessage();
req.RequestUri = uriBuilder.Uri;
req.Headers.Add("User-Agent","My C# Client"); // required, See https://developer.github.com/v3/#user-agent-required
return req;
}
}
Test :
var api = new GitHubRepoApi();
var saveAs= Path.Combine(Directory.GetCurrentDirectory(),"abc.zip");
var owner = "newbienewbie";
var token = "------your-----token--------";
var repo = "your-repo";
var @ref = "6883a92222759d574a724b5b8952bc475f580fe0"; // will be "master" by default
api.DownloadArchieveAsync(saveAs, owner,token,repo,@ref).Wait();
来源:https://stackoverflow.com/questions/58486892/read-image-from-private-github-repository-programmatically-using-c-sharp