0

I am creating an web application using c# to upload video to YouTube channel. I have generated the client secret and clientid in google api console.

My redirect uri settings:

Application urls in the google console api

But while running the application, getting the above error that

"Error 400: redirect_uri_mismatch".

Can anyone help me on this, however i am able upload using console application.

Aspx Code :

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="VideoUpload.aspx.cs" Inherits="VideoUploader.VideoUpload" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:FileUpload runat="server" id="UploadFile"/>

            <asp:Button ID="UploadBtn" Text="Upload File" OnClick="UploadBtn_Click" runat="server" Width="105px" />

            <asp:Label ID="lblMessage" runat="server"></asp:Label>
        </div>
    </form>
</body>
</html>

C# Code :

using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
using System;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace VideoUploader
{
    public partial class VideoUpload : System.Web.UI.Page
    {
        public static string uploadedFilename;
        private BaseClientService.Initializer initializer;

        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void UploadBtn_Click(object sender, EventArgs e)
        {
            if (UploadFile.HasFile)
            {
                uploadedFilename = UploadFile.FileName;
                UploadFile.SaveAs(@"C:\temp\" + UploadFile.FileName);

                try
                {
                    new VideoUpload().Run().Wait();
                }
                catch (AggregateException ex)
                {
                    foreach (var err in ex.InnerExceptions)
                    {
                        lblMessage.Text = err.Message;
                    }
                }
            }
            else
            {
                lblMessage.Text = "No File Uploaded.";
            }
        }

        private async Task Run()
        {

            UserCredential credential;
            using (var stream = new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
            {
                credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    new[] { YouTubeService.Scope.Youtube },
                    Environment.UserName,
                    CancellationToken.None
                    //new FileDataStore($"{Directory.GetCurrentDirectory()}/credentials")
                );
            }



            if (credential.Token.IsExpired(SystemClock.Default))
            {
                if (!await credential.RefreshTokenAsync(CancellationToken.None))
                {
                    Response.Write("No valid refresh token.");
                }
            }

            var youtubeService = new YouTubeService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
            });

            //YouTubeService youtubeService1 = new YouTubeService(initializer);
            youtubeService.HttpClient.Timeout = TimeSpan.FromMinutes(60);

            var video = new Video();
            video.Snippet = new VideoSnippet();
            video.Snippet.Title = "New Video Title";
            video.Snippet.Description = "Default Video Description";
            video.Snippet.Tags = new string[] { "tag1", "tag2" };
            video.Snippet.CategoryId = "22"; // See https://developers.google.com/youtube/v3/docs/videoCategories/list
            video.Status = new VideoStatus();
            video.Status.PrivacyStatus = "unlisted"; // or "private" or "public"
            //var filePath = @"C:\\Users\\gopalakrishna.s\\Pictures\\Camera Roll\\test.mp4"; // Replace with path to actual movie file.
            var filePath = @"C:\\temp\\"+uploadedFilename;

            using (var fileStream = new FileStream(filePath, FileMode.Open))
            {
                var videosInsertRequest = youtubeService.Videos.Insert(video, "snippet,status", fileStream, "video/*");
                videosInsertRequest.ProgressChanged += videosInsertRequest_ProgressChanged;
                videosInsertRequest.ResponseReceived += videosInsertRequest_ResponseReceived;

                await videosInsertRequest.UploadAsync();
            }
        }

        void videosInsertRequest_ProgressChanged(Google.Apis.Upload.IUploadProgress progress)
        {
            switch (progress.Status)
            {
                case UploadStatus.Uploading:
                    lblMessage.Text = progress.BytesSent.ToString() + " bytes sent";
                    break;

                case UploadStatus.Failed:
                    lblMessage.Text = "An error prevented the upload from completing.\n" + progress.Exception;
                    break;
            }
        }

        void videosInsertRequest_ResponseReceived(Video video)
        {
            lblMessage.Text = "Video id" + video.Id + "was successfully uploaded.";
        }    
    }
}
Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449
  • The two screenshots are the same. – mjwills Dec 09 '20 at 06:41
  • 2
    Please share a [mcve]. I am going to speculate you gave a different redirect URI. – mjwills Dec 09 '20 at 06:41
  • I have shared the code above, could you please check and help me. – Gopalakrishna Dec 09 '20 at 07:09
  • https://stackoverflow.com/questions/21132531/list-youtube-videos-using-c-sharp-and-google-apis-youtube-v3 may be of assistance. – mjwills Dec 09 '20 at 07:22
  • That article is also not working out. – Gopalakrishna Dec 09 '20 at 09:37
  • It seems like you are trying to tell Youtube to look for a localhost machine? - That would never work, since youtube's servers localhost is not your localhost. Try with your IP address after forwarding ports and such? Another thing is that if you are running this in debug mode in visual studio, outside servers cannot access the ports that your program uses. Even on your LAN. – Bjørn Dec 09 '20 at 13:54

1 Answers1

0

redirect_uri_mismatch

Means that the Redirect URI you sent with the request is not one that was registered in Google developer console for your project. The redirect URI is automatically created for you by the google .net client library.

why console works.

Console application works because it is an installed application the redirect URI is always exactly where the request came from. It doesn't really use a redirect uri in the same manner.

Web application.

With web application the request is coming from the users machine and you want it handled on your website. If you check the error message that you are getting back it will state exactly what it expected its redirect uri to be and its not one of the ones you have added in Google developer console. Knowing that you are using the google .net client library i would suggest that it also ends in /authorize

https://localhost:[someport]/authorize

Solution is to check the error message you are getting back with the redirect_uri_mismatch error message and then add that in google developer console. Remember that the port must match exactly so if your IDE is adding random ports every time you run your going to need to stop it from doing that.

GoogleWebAuthorizationBroker.AuthorizeAsync

Also please note that this method is designed for use with installed applications only it will not work when you try to host it on a website as its going to attempt to open the browser window on the machine the code is running on. Being a server that will not work.

You need to be using GoogleAuthorizationCodeFlow

Linda Lawton - DaImTo
  • 106,405
  • 32
  • 180
  • 449