【问题标题】:HttpClient GetAsync Method 403 errorHttpClient GetAsync 方法 403 错误
【发布时间】:2016-02-28 16:24:33
【问题描述】:

我正在尝试简单地显示 github 存储库。 url "https://api.github.com/search/repositories?q=pluralsight" 在我的浏览器中有效返回 json 并在 fiddler 中有效,但我的 .NET Web 应用程序中的以下内容出现 403 Forbidden 错误。谁能帮我理解一个修复?我的控制器如下:

public class HomeController : Controller
    {
    public ActionResult Index()
        {
        Tweets model = null;
        var client = new HttpClient();
        var task = client.GetAsync("https://api.github.com/search/repositories?q=pluralsight")
            .ContinueWith((taskwithresponse) =>
            {
                var response = taskwithresponse.Result;
                response.EnsureSuccessStatusCode();
                var readtask = response.Content.ReadAsAsync<Tweets>();
                readtask.Wait();
                model = readtask.Result;

            });
        task.Wait();
        return View(model.results);
        }
    }

我有一个定义如下的类(忽略它被称为 Tweets)最初试图访问 twitter api。

namespace HttpClientMVCDemo.Controllers
{
public class Tweets
    {
    public Tweet[] results;
    }
public class Tweet
    {
    [JsonProperty("name")]
    public string UserName { get; set; }
    [JsonProperty("id")]
    public string id { get; set; }
    }
}

根据以下 Amit 的类自动生成的代码视图:

@model IEnumerable<HttpClientMVCDemo.Controllers.Gits>

@{
ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
    <th>
        @Html.DisplayNameFor(model => model.total_count)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.incomplete_results)
    </th>
    <th></th>
</tr>

@foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.total_count)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.incomplete_results)
    </td>
    <td>
        @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
        @Html.ActionLink("Details", "Details", new       { /*id=item.PrimaryKey*/ }) |
        @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
    </td>
</tr>
}

【问题讨论】:

    标签: asp.net-mvc httpclient http-status-code-403


    【解决方案1】:

    这里是你的模型类中的一些修改

    第一个 Json 字符串包含 items 数组而不是 results

    而您忘记在模型类中提供 get 和 set 属性。

    所以这是新修改的模型类。

    public class Tweets
        {
            public int total_count { get; set; }
            public bool incomplete_results { get; set; }
            public List<Item> items { get; set; }
        }
    
        public class Item
        {
            public int id { get; set; }
            public string name { get; set; }
            public string full_name { get; set; }
        }
    

    要从该 url 获取数据,您需要在请求中添加 User-Agent 标头。 并将其添加到您的 web.cofig 文件中

    <system.net>
        <settings>
          <httpWebRequest useUnsafeHeaderParsing="true" />
        </settings>
      </system.net>
    

    所以这里是完整的代码。

    Tweets model = null;           
                var client = new HttpClient();
                client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "http://developer.github.com/v3/#user-agent-required");
                var task = client.GetAsync("https://api.github.com/search/repositories?q=pluralsight")
                    .ContinueWith((taskwithresponse) =>
                    {
                        var response = taskwithresponse.Result.Content.ReadAsStringAsync();
                        response.Wait();
                        model = JsonConvert.DeserializeObject<Tweets>(response.Result);
                    });
                task.Wait();
                return View(model.items);
    

    并且在你看来应该接受这种类型的模型

    @model IEnumerable<HttpClientMVCDemo.Controllers.Item>
    

    【讨论】:

    • 阿米特,我试过你的解决方案。我已经处理了 system.net 的添加。我改造了我的班级并添加了您列出的代码。现在我得到一个不同的错误“传递到字典中的模型项的类型是'System.Collections.Generic.List1[HttpClientMVCDemo.Controllers.Item]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[HttpClientMVCDemo.Controllers.Gits]'。”
    • 我无法将它装入 cmets(太长)。
    • @jaykum:用@model IEnumerable&lt;HttpClientMVCDemo.Controllers.Item&gt;替换这行@model IEnumerable&lt;HttpClientMVCDemo.Controllers.Gits&gt;
    • 好的,for each 循环中的模型有一些问题,我会尝试修复它,如果我不能稍后再发布(必须去工作)。感谢您的帮助。
    • 阿米特,对不起,工作把我带走了。我真的很感谢你的帮助。我不得不重建视图,因为我将它从 Gits 更改为 Item,现在它可以工作了。
    【解决方案2】:

    您的浏览器会自动向请求添加几个接受标头。您可能必须在请求中添加标头以避免 403。

     httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/json");
    

    类似的问题是here。最简单的方法是使用 Fiddler 来检查您的请求。

    此外,您不应在异步调用中调用 Wait。最好将操作声明为async 并调用await client.GetAsync();否则您可能会遇到死锁。见here

    【讨论】:

      【解决方案3】:

      HTTP 403:由于来自 github 站点的管理规则而被禁止。

      从 github 站点访问 api(https://api.github.com/) 需要 'User-Agent' 标头。

      这可以使用以下代码解决:

      HttpClient Client = new HttpClient();    
      Client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "http://developer.github.com/v3/#user-agent-required");
      var res = Client.GetAsync("https://api.github.com/search/repositories?q=pluralsight").Result.Content.ReadAsStringAsync().Result;
      

      参考: https://docs.github.com/en/free-pro-team@latest/rest/overview/resources-in-the-rest-api#user-agent-required

      【讨论】:

        猜你喜欢
        • 2023-04-10
        • 1970-01-01
        • 2016-04-20
        • 2013-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多