Forum Discussion
Hi Trish, sure.
// Helper function to extract the authorization code from the URL
private static string ExtractAuthorizationCode(string uri)
{
var uriObj = new Uri(uri);
var queryParams = HttpUtility.ParseQueryString(uriObj.Query);
return queryParams["code"];
}
Here's the whole class:
public static class OAuthLogin
{
private const string CsOAuthServer = "https://secure.myob.com/oauth2/account/authorize/";
private const string CsOAuthScope = "CompanyFile";
private static string _currentUri = string.Empty;
public static async Task<string> GetAuthorizationCode(IApiConfiguration config)
{
// Format the URL for the OAuth server login
string url = string.Format("{0}?client_id={1}&redirect_uri={2}&scope={3}&response_type=code",
CsOAuthServer, config.ClientId, HttpUtility.UrlEncode(config.RedirectUrl), CsOAuthScope);
// Create a new form with WebView2
var frm = new Form();
var webView2 = new WebView2
{
Dock = DockStyle.Fill
};
frm.Controls.Add(webView2);
// Set up a TaskCompletionSource to signal when the form can close
var tcs = new TaskCompletionSource<string>();
// Subscribe to NavigationCompleted to capture the OAuth redirect
webView2.CoreWebView2InitializationCompleted += (sender, args) =>
{
if (args.IsSuccess)
{
// Navigate to the OAuth login URL
webView2.CoreWebView2.Navigate(url);
}
};
// Capture the URL in NavigationStarting
webView2.NavigationStarting += (sender, args) =>
{
// Store the URI when navigation starts
_currentUri = args.Uri;
};
// Use NavigationCompleted to check if the URI contains the authorization code
webView2.NavigationCompleted += (sender, args) =>
{
if (_currentUri.Contains("code="))
{
// Extract the authorization code from the URL
string code = ExtractAuthorizationCode(_currentUri);
// Signal the TaskCompletionSource that the form can close with the code
tcs.SetResult(code);
// Close the form
frm.Invoke((MethodInvoker)(() => frm.Close()));
}
};
// Initialize WebView2 control asynchronously
await webView2.EnsureCoreWebView2Async(null);
frm.Size = new Size(800, 600);
frm.Show();
// Wait until the TaskCompletionSource is signaled (form is closed)
string authCode = await tcs.Task;
return authCode;
}
// Helper function to extract the authorization code from the URL
private static string ExtractAuthorizationCode(string uri)
{
var uriObj = new Uri(uri);
var queryParams = HttpUtility.ParseQueryString(uriObj.Query);
return queryParams["code"];
}
}
Hi Steve and other developers.
This thread was very helpful in getting my solution running again. Thank you for sharing the helpful information!
Just a note that I ran into a problem when my app was installed in the Program Files (x86) folder. WebView2 needs to create a user data folder and it can't create that folder under Program Files. The version I am using doesn't give an error message when it can't create the folder - it just didn't display the browser.
I found the fix at https://github.com/MicrosoftEdge/WebView2Feedback/issues/297 - there is code there to set the data folder:
public BrowserForm(string url = null)
{
InitializeComponent();
InitializeBrowser(url);
}
private async void InitializeBrowser(string url = null)
{
var userDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\SoftwareName";
var env = await CoreWebView2Environment.CreateAsync(null, userDataFolder);
await webView21.EnsureCoreWebView2Async(env);
webView21.Source = new UriBuilder(url ?? Settings.Default.HomePage).Uri;
}
Hope this helps!
Clancy