2

I have created a PCL in Visual Studio targeting: .NET 4.5, Windows Phone 8, Windows Store Apps, Xamarin Android and Xamarin iOS.

This PCL integrates with the YouTube Data API v3 via HttpClient requests (have some issues using the client library directly).

I have written and successfully run unit tests which test this integration in Visual Studio (test project referencing PCL project), however, when I consume those methods in a Xamarin Android project (in Xamarin Studio) I am getting a Forbidden 403 error on one of the GET methods (search.list - GetStringAsync below), POST methods appear to work fine.

The method in question is as follows:-

public async Task<Google.Apis.YouTube.v3.Data.SearchListResponse> GetVideosForChannelManual(string channelId, string apiKey, string pageToken)
    {
        var requestString = "https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=50";
        requestString += "&channelId=" + channelId;
        requestString += "&key=" + apiKey;

        if (!String.IsNullOrEmpty(pageToken))
        {
            requestString += "&pageToken=" + pageToken;
        }

        using (HttpClient client = new HttpClient())
        {
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            var task = await client.GetStringAsync(requestString);
            var deserializedResponse = JsonConvert.DeserializeObject<Google.Apis.YouTube.v3.Data.SearchListResponse>(task);
            return deserializedResponse;
        }
    }

The detail of the exception is below:-

    [0] {System.Net.Http.HttpRequestException: 403 (Forbidden)
  at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode () [0x00000] in <filename unknown>:0 
  at System.Net.Http.HttpClient+<GetStringAsync>c__async5.MoveNext () [0x00000] in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.TaskAwaiter`1[System.String].GetResult () [0x00000] in <filename unknown>:0 
  at YouTubeHelpers.YouTubeRepository+<GetVideosForChannelManual>d__27.MoveNext () [0x000fa] in c:\...\YouTubeRepository.cs:187 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <filename unknown>:0 
  at System.Runtime.CompilerServices.TaskAwaiter`1[Google.Apis.YouTube.v3.Data.SearchListResponse].GetResult () [0x00000] in <filename unknown>:0 
  at YouTubeHelpers.YouTubeRepository+<GetAllVideosForChannelManual>d__20.MoveNext () [0x00061] in c:\..\YouTubeRepository.cs:160 } System.Net.Http.HttpRequestException

My initial thoughts are that the Http request headers are different when running it on Android compared to directly in VS and so attempted to compare in Fiddler using a reverse proxy on the emulator (problem exists in emulator and on hardware device), but I was unable to get the app to send web traffic through the proxy (even though browser traffic was sent to fiddler correctly).

Presumably the HttpClient handler would have to be set for this proxy, but with limited access to System.Net libraries in the PCL it wasn't clear how to achieve this.

Is there something which I should be setting additionally for these GET requests bearing in mind that in the POST requests (insert like, insert subscription for example) where I explicitly send an OAuth2 token as an authentication header (required) work fine?

Any advice would be appreciated.

UPDATE

Tried using ModernHttpClient, but the exception still persists. Still feel this is something to do with the request headers, but no smoking gun as yet.

3
  • 1
    Try ModernHttpClient from NuGet. It is cross platform layer above native clients and it uses System.Net.Http (it is fully compatible with HttpClient) Commented Jun 27, 2014 at 19:03
  • @xakz Thanks for the comment. I did consider the ModernHttpClient, but thought it was worth understanding the underlying issue here first. Assuming I can just add the NuGet package to the PCL I'll give this a go and see if it resolves the issue. Commented Jun 27, 2014 at 21:44
  • @xakz I have tried the requests with ModernHttpClient and sadly see the same exception. As advertised though the calls probably are a bit quicker, so I may continue to use it. I may have to try some other GET requests as a comparison as it has no problems with my POST requests, likely due to the passing of the auth token. Thanks again. Commented Jun 27, 2014 at 22:14

1 Answer 1

2

So the issue was limited to the YouTube data API and not a generic PCL issue (thankfully). It seems that when making an unauthenticated request to the YouTube API (such as search etc) then you need to use the Web API Key, rather than an Android API key?! Even though when making an authenticated request (using OAuth2) you need to use the Android Key and associate the request with the solutions SHA1 key. Hopefully this may help someone else if they encounter this issue too.

I suppose this does raise the question of why there is an option to add an Android API key for the Public API access when it doesn't appear to work and the Web API key should be used?

Sign up to request clarification or add additional context in comments.

1 Comment

Did you ever get to see your requests in Fiddler?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.