Read image from private GitHub repository programmatically using C#

谁说胖子不能爱 提交于 2021-01-29 10:16:25

问题


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:

  1. 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 :

  1. Download file

For more details, please refer to https://developer.github.com/v3/repos/contents/#get-contents.




回答2:


How to fix :

  1. The URL is changed to GET /repos/:owner/:repo/:archive_format/:ref. See https://developer.github.com/v3/repos/contents/#get-archive-link

    For private repositories, these links are temporary and expire after five minutes.

    GET /repos/:owner/:repo/:archive_format/:ref

  2. 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

  3. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!