Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient GetAsync Method 403 error

I am trying a simple display of github repositories. The url "https://api.github.com/search/repositories?q=pluralsight" works in my browser return json and works in fiddler but the following in my .NET Web App is getting a 403 Forbidden error. Can anyone help me understand a fix? My controller is as follows:

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

I have a class defined as follows (ignore that it is called Tweets) originally was trying to access 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; }
    }
}

Code view auto generated based on Amit's classes below:

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

like image 911
jaykum Avatar asked Mar 14 '23 03:03

jaykum


1 Answers

Well here are some modification in your model class

First Json string contain array of items not results

and you forget to provide get and set propertyin model class.

So This is new modified model class.

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

And to get data from that url, You need to add User-Agent header in request. And also add this in your web.cofig file

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

So here is complete code.

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

And in your view should accept this type of model

@model IEnumerable<HttpClientMVCDemo.Controllers.Item>
like image 137
Amit Kumar Avatar answered Mar 15 '23 15:03

Amit Kumar