【问题标题】:Read image from private GitHub repository programmatically using C#使用 C# 以编程方式从私有 GitHub 存储库中读取图像
【发布时间】:2020-02-17 13:52:37
【问题描述】:

需要使用 C# 将图像从私有 git 存储库存储到 blob。尝试使用以下代码,但出现 404 错误。

我正在使用以下代码 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);
}

注意:可以从公共存储库中获取

【问题讨论】:

  • 获取 404 表明资源(在本例中为图像)不在 URL 指定的位置。您可以发布或检查您的网址以查看其是否正确吗?如果它是正确的,但(例如)身份验证失败,它应该给你 404 以外的东西
  • 我正在使用个人访问令牌来获取图像。图片 URL 是正确的(如果我将存储库设为公开,我可以使用相同的 URL 获取图片)我怀疑令牌没有进行身份验证。但我在 github 中授予了该令牌的所有权限
  • 您提供的链接只是一个包含多个 sn-ps 代码的 stackoverflow 问题。您正在运行的实际代码是什么?存储库是否由为其创建访问令牌的同一帐户拥有?如果您无权访问私有仓库,github 会给出 404
  • 正如 LampToast 指出的那样,我错误地认为 GitHub 在未经授权时返回 401,而实际上它返回 404。您能否给我们匿名链接(将您的 GitHub 名称替换为 YourName 之类的名称)。另外edit你的问题是添加你正在使用的代码
  • 我使用的链接“github.com/ramakrishnareddy2108/FileAccessTest/blob/master/…”在私有存储库中

标签: c# image asp.net-core github azure-blob-storage


【解决方案1】:

根据您提供的信息,您使用了错误的网址进行下载。关于如何获取下载地址,请参考以下步骤:

  1. 使用以下网址获取下载地址
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>

repose body 会告诉你下载地址 例如 :

  1. 下载文件

更多详情请参考https://developer.github.com/v3/repos/contents/#get-contents

【讨论】:

  • @RamakrishnaReddy 如果您的问题已经解决,请您接受答案吗?它可能会帮助更多有类似问题的人。
【解决方案2】:

如何解决:

  1. 网址更改为GET /repos/:owner/:repo/:archive_format/:ref。见https://developer.github.com/v3/repos/contents/#get-archive-link

    对于私有存储库,这些链接是临时的,五分钟后过期。

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

  2. 您不应使用基本身份验证传递凭据。相反,您应该按照官方文档创建一个 token。见https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line

  3. 最后,您需要传递一个额外的 User-Agent 标头。 GitHub API 需要它。见https://developer.github.com/v3/#user-agent-required

    所有 API 请求都必须包含有效的 User-Agent 标头。

演示

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;
    }
}

测试:

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();

【讨论】:

    猜你喜欢
    • 2015-04-18
    • 2023-03-20
    • 2012-10-08
    • 2019-12-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-24
    • 2016-09-04
    • 1970-01-01
    相关资源
    最近更新 更多