From 1ff9133b4a207cb1c65e40464a1ac1baf520deb5 Mon Sep 17 00:00:00 2001 From: Aleksey Nemiro Date: Sun, 10 Jul 2016 22:36:03 +0300 Subject: [PATCH] v1.11 * New structure of the repository; * Added the ability to upload large files; * Strong name. Fixed #12 Fixed #13 --- Release Notes.md => CHANGELOG.md | 132 +- README.md | 62 +- README.ru.md | 135 + bin/ReadMe.md | 6 - bin/net35/Nemiro.OAuth.XML | 9540 ----------------- bin/net35/Nemiro.OAuth.dll | Bin 126464 -> 0 bytes bin/net40/Nemiro.OAuth.XML | 9540 ----------------- bin/net40/Nemiro.OAuth.dll | Bin 126976 -> 0 bytes bin/net45/Nemiro.OAuth.XML | 9540 ----------------- bin/net45/Nemiro.OAuth.dll | Bin 126976 -> 0 bytes bin/net451/Nemiro.OAuth.XML | 9540 ----------------- bin/net451/Nemiro.OAuth.dll | Bin 126976 -> 0 bytes .../AspNetWebFormsCustomClient.VB.sln | 22 + .../AspNetWebFormsCustomClient.VB.vbproj | 16 +- .../Default.aspx | 0 .../Default.aspx.designer.vb | 0 .../Default.aspx.vb | 0 .../ExternalLoginResult.aspx | 0 .../ExternalLoginResult.aspx.designer.vb | 0 .../ExternalLoginResult.aspx.vb | 0 .../AspNetWebFormsCustomClient.VB/Global.asax | 0 .../Global.asax.vb | 0 .../My Project/Application.Designer.vb | 0 .../My Project/Application.myapp | 0 .../My Project/AssemblyInfo.vb | 0 .../My Project/MyExtensions/MyWebExtension.vb | 0 .../My Project/Resources.Designer.vb | 0 .../My Project/Resources.resx | 0 .../My Project/Settings.Designer.vb | 0 .../My Project/Settings.settings | 0 .../MyFacebookClient.vb | 0 .../MyTwitterClient.vb | 0 .../Web.Debug.config | 0 .../Web.Release.config | 0 .../AspNetWebFormsCustomClient.VB/Web.config | 0 .../packages.config | 2 +- .../AspNetWebFormsCustomClient.csproj | 14 +- .../AspNetWebFormsCustomClient.sln | 22 + .../AspNetWebFormsCustomClient/Default.aspx | 0 .../Default.aspx.cs | 0 .../Default.aspx.designer.cs | 0 .../ExternalLoginResult.aspx | 0 .../ExternalLoginResult.aspx.cs | 0 .../ExternalLoginResult.aspx.designer.cs | 0 .../AspNetWebFormsCustomClient/Global.asax | 0 .../AspNetWebFormsCustomClient/Global.asax.cs | 0 .../MyFacebookClient.cs | 0 .../MyTwitterClient.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../Web.Debug.config | 0 .../Web.Release.config | 0 .../AspNetWebFormsCustomClient/Web.config | 0 .../packages.config | 2 +- .../AspNetWebFormsMulticlients.csproj | 18 +- .../AspNetWebFormsMulticlients.sln | 22 + .../AspNetWebFormsMulticlients/Default.aspx | 0 .../Default.aspx.cs | 0 .../Default.aspx.designer.cs | 0 .../ExternalLoginResult.aspx | 0 .../ExternalLoginResult.aspx.cs | 0 .../ExternalLoginResult.aspx.designer.cs | 0 .../AspNetWebFormsMulticlients/Global.asax | 0 .../AspNetWebFormsMulticlients/Global.asax.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../AspNetWebFormsMulticlients/README.md | 0 .../RedirectToAuth.aspx | 0 .../RedirectToAuth.aspx.cs | 0 .../RedirectToAuth.aspx.designer.cs | 0 .../Web.Debug.config | 0 .../Web.Release.config | 0 .../AspNetWebFormsMulticlients/Web.config | 0 .../packages.config | 4 + .../AspWebFormsPopup/AspWebFormsPopup.csproj | 18 +- .../AspWebFormsPopup/AspWebFormsPopup.sln | 22 + .../AspWebFormsPopup/Default.aspx | 0 .../AspWebFormsPopup/Default.aspx.cs | 0 .../AspWebFormsPopup/Default.aspx.designer.cs | 0 .../AspWebFormsPopup/ExternalLoginResult.aspx | 0 .../ExternalLoginResult.aspx.cs | 0 .../ExternalLoginResult.aspx.designer.cs | 0 .../AspWebFormsPopup/Global.asax | 0 .../AspWebFormsPopup/Global.asax.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../AspWebFormsPopup/README.md | 0 .../AspWebFormsPopup/RedirectToAuth.aspx | 0 .../AspWebFormsPopup/RedirectToAuth.aspx.cs | 0 .../RedirectToAuth.aspx.designer.cs | 0 .../AspWebFormsPopup/Web.Debug.config | 0 .../AspWebFormsPopup/Web.Release.config | 0 {src => examples}/AspWebFormsPopup/Web.config | 0 examples/AspWebFormsPopup/packages.config | 4 + .../CodeProjectForumViewer.csproj | 18 +- .../CodeProjectForumViewer.sln | 22 + .../CodeProjectForumViewer/LICENSE | 0 .../MainForm.Designer.cs | 0 .../CodeProjectForumViewer/MainForm.cs | 0 .../CodeProjectForumViewer/MainForm.resx | 0 .../CodeProjectForumViewer/Program.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../Properties/Resources.Designer.cs | 0 .../Properties/Resources.resx | 0 .../Properties/Settings.Designer.cs | 0 .../Properties/Settings.settings | 0 .../CodeProjectForumViewer/README.md | 0 .../Resources/codeproject.ico | Bin .../Resources/progress.gif | Bin .../ThreadViewer.Designer.cs | 0 .../CodeProjectForumViewer/ThreadViewer.cs | 0 .../CodeProjectForumViewer/ThreadViewer.resx | 0 .../CodeProjectForumViewer/app.config | 0 .../CodeProjectForumViewer/packages.config | 5 + .../CodeProjectForumViewer/preview.jpg | Bin {src => examples}/CustomClients/MyClient.cs | 0 {src => examples}/CustomClients/MyClient.vb | 0 .../DemoSite}/Content/css/Site.css | 3 +- .../DemoSite}/Content/css/jquery.jsonview.css | 0 .../DemoSite}/Content/images/config.png | Bin .../DemoSite}/Content/images/cross.png | Bin .../DemoSite}/Content/images/help.png | Bin .../DemoSite}/Content/images/preview.png | Bin .../DemoSite}/Content/images/processing.gif | Bin .../DemoSite}/Content/images/processing2.gif | Bin .../DemoSite}/Content/images/tick.png | Bin .../Content/js/jquery-1.5.1-vsdoc.js | 0 .../DemoSite}/Content/js/jquery-1.5.1.min.js | 0 .../DemoSite}/Content/js/jquery.jsonview.js | 0 .../Content/js/jquery.unobtrusive-ajax.js | 0 .../Content/js/jquery.unobtrusive-ajax.min.js | 0 .../Content/js/jquery.validate-vsdoc.js | 0 .../DemoSite}/Content/js/jquery.validate.js | 0 .../Content/js/jquery.validate.min.js | 0 .../Content/js/jquery.validate.unobtrusive.js | 0 .../js/jquery.validate.unobtrusive.min.js | 0 .../DemoSite}/Controllers/ApiController.cs | 10 +- .../DemoSite}/Controllers/CodeProject.cs | 4 +- .../DemoSite}/Controllers/Dropbox.cs | 4 +- .../DemoSite}/Controllers/Facebook.cs | 4 +- .../DemoSite}/Controllers/Google.cs | 4 +- .../DemoSite}/Controllers/HomeController.cs | 12 +- .../DemoSite}/Controllers/MailRu.cs | 4 +- .../DemoSite}/Controllers/Twitter.cs | 4 +- .../DemoSite}/Controllers/VK.cs | 4 +- .../DemoSite}/Controllers/Yandex.cs | 4 +- .../DemoSite/DemoOAuth.csproj | 247 +- examples/DemoSite/DemoOAuth.sln | 22 + examples/DemoSite/Global.asax | 1 + .../DemoSite}/Global.asax.cs | 17 +- examples/DemoSite/Images.Designer.cs | 283 + .../DemoSite}/Images.resx | 0 examples/DemoSite/Properties/AssemblyInfo.cs | 35 + .../ReadMe.md => examples/DemoSite/README.md | 0 .../DemoSite}/Resources/amazon.dat | Bin .../DemoSite}/Resources/amazon100.dat | Bin .../DemoSite}/Resources/assembla.dat | Bin .../DemoSite}/Resources/codeproject | Bin .../DemoSite}/Resources/dropbox.dat | Bin .../DemoSite}/Resources/empty.dat | Bin .../DemoSite}/Resources/error.dat | Bin .../DemoSite}/Resources/facebook100.dat | Bin .../DemoSite}/Resources/foursquare.dat | Bin .../DemoSite}/Resources/github100.dat | Bin .../DemoSite}/Resources/google100.dat | Bin .../DemoSite}/Resources/instagram.dat | Bin .../DemoSite}/Resources/linkedin.dat | Bin .../DemoSite}/Resources/live.dat | Bin .../DemoSite}/Resources/mail.ru100.dat | Bin .../DemoSite}/Resources/odnoklassniki100.dat | Bin .../DemoSite}/Resources/soundcloud.dat | Bin .../DemoSite}/Resources/sourceforge.dat | Bin .../DemoSite}/Resources/tumblr.dat | Bin .../DemoSite}/Resources/twitter100.dat | Bin .../DemoSite}/Resources/vk100.dat | Bin .../DemoSite}/Resources/yahoo.dat | Bin .../DemoSite}/Resources/yandex100.dat | Bin examples/DemoSite/Strings.Designer.cs | 531 + examples/DemoSite/Strings.resx | 322 + .../DemoSite}/Strings.ru.Designer.cs | 0 examples/DemoSite/Strings.ru.resx | 377 + .../DemoSite}/Views/Home/Index.cshtml | 57 +- .../DemoSite}/Views/Home/Result.cshtml | 12 +- .../DemoSite}/Views/Shared/CodeProject.cshtml | 0 .../DemoSite}/Views/Shared/Dropbox.cshtml | 0 .../DemoSite}/Views/Shared/Error.cshtml | 0 .../DemoSite/Views/Shared/Facebook.cshtml | 4 + examples/DemoSite/Views/Shared/Google.cshtml | 1 + examples/DemoSite/Views/Shared/Mail.Ru.cshtml | 2 + examples/DemoSite/Views/Shared/Twitter.cshtml | 2 + examples/DemoSite/Views/Shared/VK.cshtml | 3 + examples/DemoSite/Views/Shared/Yandex.cshtml | 4 + .../DemoSite}/Views/Shared/_Layout.cshtml | 1 - examples/DemoSite/Views/web.config | 42 + .../DemoSite}/Web.Debug.config | 15 +- .../DemoSite}/Web.Release.config | 15 +- .../DemoSite}/Web.config | 66 +- examples/DemoSite/packages.config | 13 + .../DemoSite}/receiver.html | 0 .../DropBoxWebForms/Default.aspx | 0 .../DropBoxWebForms/Default.aspx.cs | 0 .../DropBoxWebForms/Default.aspx.designer.cs | 0 .../DropBoxWebForms/DropBoxWebForms.csproj | 24 +- .../DropBoxWebForms/DropBoxWebForms.sln | 8 +- .../DropBoxWebForms/ExternalLoginResult.aspx | 0 .../ExternalLoginResult.aspx.cs | 0 .../ExternalLoginResult.aspx.designer.cs | 0 .../DropBoxWebForms/Global.asax | 0 .../DropBoxWebForms/Global.asax.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../DropBoxWebForms/Web.Debug.config | 0 .../DropBoxWebForms/Web.Release.config | 0 .../DropBoxWebForms/Web.config | 0 examples/DropBoxWebForms/packages.config | 4 + .../DropboxExample/Download.Designer.cs | 39 +- {src => examples}/DropboxExample/Download.cs | 2 +- .../DropboxExample/Download.resx | 0 .../DropboxExample/DropboxExample.csproj | 22 +- examples/DropboxExample/DropboxExample.sln | 22 + .../DropboxExample/InputBox.Designer.cs | 2 +- {src => examples}/DropboxExample/InputBox.cs | 2 +- .../DropboxExample/InputBox.resx | 0 {src => examples}/DropboxExample/LICENSE | 0 .../DropboxExample/MainForm.Designer.cs | 2 +- {src => examples}/DropboxExample/MainForm.cs | 34 +- .../DropboxExample/MainForm.resx | 0 {src => examples}/DropboxExample/Program.cs | 2 +- .../DropboxExample/Properties/AssemblyInfo.cs | 6 +- .../Properties/Resources.Designer.cs | 0 .../DropboxExample/Properties/Resources.resx | 0 .../Properties/Settings.Designer.cs | 0 .../Properties/Settings.settings | 0 .../DropboxExample/README.md | 0 .../DropboxExample/Resources/alert.png | Bin .../DropboxExample/Resources/bin.png | Bin .../DropboxExample/Resources/disk.png | Bin .../DropboxExample/Resources/disk__plus.png | Bin .../Resources/document__pencil.png | Bin .../DropboxExample/Resources/error.png | Bin .../DropboxExample/Resources/folder__plus.png | Bin .../DropboxExample/Resources/loader1.gif | Bin .../DropboxExample/Resources/loader2.gif | Bin .../DropboxExample/Resources/success.png | Bin .../DropboxExample/Upload.Designer.cs | 51 +- {src => examples}/DropboxExample/Upload.cs | 78 +- {src => examples}/DropboxExample/Upload.resx | 0 {src => examples}/DropboxExample/app.config | 14 +- {src => examples}/DropboxExample/dropbox.ico | Bin examples/DropboxExample/packages.config | 5 + {src => examples}/DropboxExample/preview.png | Bin .../GoogleDriveWebForms/Default.aspx | 0 .../GoogleDriveWebForms/Default.aspx.cs | 46 +- .../Default.aspx.designer.cs | 0 .../ExternalLoginResult.aspx | 0 .../ExternalLoginResult.aspx.cs | 0 .../ExternalLoginResult.aspx.designer.cs | 0 .../GoogleDriveWebForms/Global.asax | 0 .../GoogleDriveWebForms/Global.asax.cs | 0 .../GoogleDriveWebForms.csproj | 24 +- .../GoogleDriveWebForms.sln | 8 +- .../Properties/AssemblyInfo.cs | 0 .../GoogleDriveWebForms/Web.Debug.config | 0 .../GoogleDriveWebForms/Web.Release.config | 0 examples/GoogleDriveWebForms/Web.config | 20 + examples/GoogleDriveWebForms/packages.config | 4 + .../GrantTypeClientCredentials.sln | 22 + .../GrantTypeClientCredentials.vbproj | 11 +- .../GrantTypeClientCredentials/Module1.vb | 0 .../My Project/Application.Designer.vb | 0 .../My Project/Application.myapp | 0 .../My Project/AssemblyInfo.vb | 0 .../My Project/Resources.Designer.vb | 0 .../My Project/Resources.resx | 0 .../My Project/Settings.Designer.vb | 0 .../My Project/Settings.settings | 0 .../GrantTypeClientCredentials/app.config | 0 .../packages.config | 4 + .../MyDropBox/App.config | 12 +- .../MyDropBox/Form1.Designer.cs | 0 .../MyDropBox => examples}/MyDropBox/Form1.cs | 75 +- .../MyDropBox/Form1.resx | 0 .../MyDropBox/MyDropBox.csproj | 12 +- {src => examples}/MyDropBox/MyDropBox.sln | 2 +- .../MyDropBox/Program.cs | 3 - .../MyDropBox/Properties/AssemblyInfo.cs | 0 .../Properties/Resources.Designer.cs | 0 .../MyDropBox/Properties/Resources.resx | 0 .../MyDropBox/Properties/Settings.Designer.cs | 0 .../MyDropBox/Properties/Settings.settings | 0 .../MyDropBox/Watch on YouTube.url | 0 examples/MyDropBox/packages.config | 5 + .../Test}/Test.CSharp.AspMvc/Content/Site.css | 0 .../Controllers/HomeController.cs | 0 .../Test}/Test.CSharp.AspMvc/Global.asax | 0 .../Test}/Test.CSharp.AspMvc/Global.asax.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../Test.CSharp.AspMvc.csproj | 42 +- .../Views/Home/ExternalLoginResult.cshtml | 0 .../Views/Home/Index.cshtml | 0 .../Views/Shared/Error.cshtml | 0 .../Views/Shared/_Layout.cshtml | 0 .../Test}/Test.CSharp.AspMvc/Views/Web.config | 0 .../Views/_ViewStart.cshtml | 0 .../Test}/Test.CSharp.AspMvc/Web.Debug.config | 0 .../Test.CSharp.AspMvc/Web.Release.config | 0 .../Test}/Test.CSharp.AspMvc/Web.config | 26 +- .../Test/Test.CSharp.AspMvc/packages.config | 8 + .../Test.CSharp.AspWebForms/Default.aspx | 0 .../Test.CSharp.AspWebForms/Default.aspx.cs | 0 .../Default.aspx.designer.cs | 0 .../ExternalLoginResult.aspx | 0 .../ExternalLoginResult.aspx.cs | 0 .../ExternalLoginResult.aspx.designer.cs | 0 .../Test}/Test.CSharp.AspWebForms/Global.asax | 0 .../Test.CSharp.AspWebForms/Global.asax.cs | 0 .../Test}/Test.CSharp.AspWebForms/Icon.ashx | 0 .../Test.CSharp.AspWebForms/Icon.ashx.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../Test}/Test.CSharp.AspWebForms/Site.css | 0 .../Test.CSharp.AspWebForms.csproj | 16 +- .../Test.CSharp.AspWebForms/Web.Debug.config | 0 .../Web.Release.config | 0 .../Test/Test.CSharp.AspWebForms}/Web.config | 0 .../Test.CSharp.AspWebForms/packages.config | 4 + .../Test.CSharp.WinForms/Form1.Designer.cs | 0 .../Test}/Test.CSharp.WinForms/Form1.cs | 0 .../Test}/Test.CSharp.WinForms/Form1.resx | 0 .../Test.CSharp.WinForms/Form2.Designer.cs | 0 .../Test}/Test.CSharp.WinForms/Form2.cs | 0 .../Test}/Test.CSharp.WinForms/Form2.resx | 0 .../Test}/Test.CSharp.WinForms/Program.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../Properties/Resources.Designer.cs | 0 .../Properties/Resources.resx | 0 .../Properties/Settings.Designer.cs | 0 .../Properties/Settings.settings | 0 .../Test.CSharp.WinForms.csproj | 11 +- .../VkontakteFriends.Designer.cs | 0 .../Test.CSharp.WinForms/VkontakteFriends.cs | 0 .../VkontakteFriends.resx | 0 .../Test}/Test.CSharp.WinForms/app.config | 0 .../Test/Test.CSharp.WinForms/packages.config | 4 + .../Test}/Test.Resources/Images.Designer.cs | 0 examples/Test/Test.Resources/Images.resx | 187 + .../Test.Resources/Properties/AssemblyInfo.cs | 0 .../Test}/Test.Resources/ReadMe.txt | 0 .../Test/Test.Resources/Resources/amazon.dat | Bin 0 -> 3390 bytes .../Test.Resources/Resources/amazon100.dat | Bin 0 -> 6724 bytes .../Test.Resources/Resources/assembla.dat | Bin 0 -> 5218 bytes .../Test/Test.Resources/Resources/codeproject | Bin 0 -> 7384 bytes .../Test/Test.Resources/Resources/dropbox.dat | Bin 0 -> 4576 bytes .../Test/Test.Resources/Resources/empty.dat | Bin 0 -> 609 bytes .../Test/Test.Resources/Resources/error.dat | Bin 0 -> 1380 bytes .../Test.Resources/Resources/facebook100.dat | Bin 0 -> 942 bytes .../Test.Resources/Resources/foursquare.dat | Bin 0 -> 4469 bytes .../Test.Resources/Resources/github100.dat | Bin 0 -> 2344 bytes .../Test.Resources/Resources/google100.dat | Bin 0 -> 2144 bytes .../Test.Resources/Resources/instagram.dat | Bin 0 -> 3353 bytes .../Test.Resources/Resources/linkedin.dat | Bin 0 -> 1890 bytes .../Test/Test.Resources/Resources/live.dat | Bin 0 -> 3157 bytes .../Test.Resources/Resources/mail.ru100.dat | Bin 0 -> 3793 bytes .../Resources/odnoklassniki100.dat | Bin 0 -> 9055 bytes .../Test.Resources/Resources/soundcloud.dat | Bin 0 -> 1958 bytes .../Test.Resources/Resources/sourceforge.dat | Bin 0 -> 2851 bytes .../Test/Test.Resources/Resources/tumblr.dat | Bin 0 -> 1821 bytes .../Test.Resources/Resources/twitter100.dat | Bin 0 -> 1800 bytes .../Test/Test.Resources/Resources/vk100.dat | Bin 0 -> 3457 bytes .../Test/Test.Resources/Resources/yahoo.dat | Bin 0 -> 3972 bytes .../Test.Resources/Resources/yandex100.dat | Bin 0 -> 2726 bytes .../Test}/Test.Resources/Strings.Designer.cs | 0 .../Test}/Test.Resources/Strings.resx | 0 .../Test.Resources/Strings.ru.Designer.cs | 0 .../Test}/Test.Resources/Strings.ru.resx | 0 .../Test.Resources/Test.Resources.csproj | 5 + examples/Test/Test.Resources/packages.config | 4 + .../Test}/Test.VB.AspMvc/Content/Site.css | 0 .../Controllers/HomeController.vb | 0 .../Test}/Test.VB.AspMvc/Global.asax | 0 .../Test}/Test.VB.AspMvc/Global.asax.vb | 0 .../My Project/Application.Designer.vb | 0 .../My Project/Application.myapp | 0 .../Test.VB.AspMvc/My Project/AssemblyInfo.vb | 0 .../My Project/Resources.Designer.vb | 0 .../Test.VB.AspMvc/My Project/Resources.resx | 0 .../My Project/Settings.Designer.vb | 0 .../My Project/Settings.settings | 0 .../Test.VB.AspMvc/Test.VB.AspMvc.vbproj | 35 +- .../Views/Home/ExternalLoginResult.vbhtml | 0 .../Test.VB.AspMvc/Views/Home/Index.vbhtml | 0 .../Test.VB.AspMvc/Views/Shared/Error.vbhtml | 0 .../Views/Shared/_Layout.vbhtml | 0 .../Test/Test.VB.AspMvc}/Views/Web.config | 0 .../Test.VB.AspMvc/Views/_ViewStart.vbhtml | 0 .../Test/Test.VB.AspMvc}/Web.Debug.config | 0 .../Test/Test.VB.AspMvc}/Web.Release.config | 0 .../Test}/Test.VB.AspMvc/Web.config | 26 +- examples/Test/Test.VB.AspMvc/packages.config | 8 + .../Test}/Test.VB.AspWebForms/Default.aspx | 0 .../Default.aspx.designer.vb | 0 .../Test}/Test.VB.AspWebForms/Default.aspx.vb | 0 .../ExternalLoginResult.aspx | 0 .../ExternalLoginResult.aspx.designer.vb | 0 .../ExternalLoginResult.aspx.vb | 0 .../Test}/Test.VB.AspWebForms/Global.asax | 0 .../Test}/Test.VB.AspWebForms/Global.asax.vb | 0 .../Test}/Test.VB.AspWebForms/Icon.ashx | 0 .../Test}/Test.VB.AspWebForms/Icon.ashx.vb | 0 .../My Project/Application.Designer.vb | 0 .../My Project/Application.myapp | 0 .../My Project/AssemblyInfo.vb | 0 .../My Project/MyExtensions/MyWebExtension.vb | 0 .../My Project/Resources.Designer.vb | 0 .../My Project/Resources.resx | 0 .../My Project/Settings.Designer.vb | 0 .../My Project/Settings.settings | 0 .../Test}/Test.VB.AspWebForms/Site.css | 0 .../Test.VB.AspWebForms.vbproj | 14 +- .../Test.VB.AspWebForms}/Web.Debug.config | 0 .../Test.VB.AspWebForms}/Web.Release.config | 0 .../Test}/Test.VB.AspWebForms/Web.config | 0 .../Test/Test.VB.AspWebForms/packages.config | 4 + .../Test}/Test.VB.WinForms/App.config | 0 .../Test}/Test.VB.WinForms/Form1.Designer.vb | 0 .../Test}/Test.VB.WinForms/Form1.resx | 0 .../Test}/Test.VB.WinForms/Form1.vb | 0 .../Test}/Test.VB.WinForms/Form2.Designer.vb | 0 .../Test}/Test.VB.WinForms/Form2.resx | 0 .../Test}/Test.VB.WinForms/Form2.vb | 0 .../My Project/Application.Designer.vb | 0 .../My Project/Application.myapp | 0 .../My Project/AssemblyInfo.vb | 0 .../My Project/Resources.Designer.vb | 0 .../My Project/Resources.resx | 0 .../My Project/Settings.Designer.vb | 0 .../My Project/Settings.settings | 0 .../Test.VB.WinForms/Test.VB.WinForms.vbproj | 11 +- .../VkontakteFriends.Designer.vb | 0 .../Test.VB.WinForms/VkontakteFriends.resx | 0 .../Test.VB.WinForms/VkontakteFriends.vb | 0 .../Test/Test.VB.WinForms/packages.config | 4 + examples/Test/Test.sln | 84 + .../TwitterExample.VB/App.config | 0 {src => examples}/TwitterExample.VB/LICENSE | 0 .../TwitterExample.VB/MainForm.Designer.vb | 2 +- .../TwitterExample.VB/MainForm.resx | 0 .../TwitterExample.VB/MainForm.vb | 12 +- .../My Project/Application.Designer.vb | 0 .../My Project/Application.myapp | 0 .../My Project/AssemblyInfo.vb | 0 .../My Project/Resources.Designer.vb | 0 .../My Project/Resources.resx | 0 .../My Project/Settings.Designer.vb | 0 .../My Project/Settings.settings | 0 .../TwitterExample.VB/My Project/app.manifest | 0 .../TwitterExample.VB/README.md | 0 .../TwitterExample.VB/Resources/alert.png | Bin .../TwitterExample.VB/Resources/error.png | Bin .../TwitterExample.VB/Resources/loader1.gif | Bin .../TwitterExample.VB/Resources/loader2.gif | Bin .../TwitterExample.VB/Resources/success.png | Bin .../TwitterExample.VB/TwitterExample.VB.sln | 22 + .../TwitterExample.VB.vbproj | 18 +- .../TwitterExample.VB/TwitterItem.Designer.vb | 2 +- .../TwitterExample.VB/TwitterItem.resx | 0 .../TwitterExample.VB/TwitterItem.vb | 2 +- examples/TwitterExample.VB/packages.config | 5 + .../TwitterExample.VB/preview.png | Bin .../TwitterExample.VB/twitter.ico | Bin .../WebForms35/Default.aspx | 0 .../WebForms35/Default.aspx.cs | 0 .../WebForms35/Default.aspx.designer.cs | 0 .../WebForms35/ExternalLoginResult.aspx | 0 .../WebForms35/ExternalLoginResult.aspx.cs | 0 .../ExternalLoginResult.aspx.designer.cs | 0 .../WebForms35/Global.asax | 0 .../WebForms35/Global.asax.cs | 0 .../WebForms35/Properties/AssemblyInfo.cs | 0 .../WebForms35/Web.Debug.config | 0 .../WebForms35/Web.Release.config | 0 .../WebForms35/Web.config | 0 .../WebForms35/WebForms35.csproj | 4 +- {src => examples}/WebForms35/WebForms35.sln | 2 +- .../WebForms35/packages.config | 2 +- .../AspNetWebFormsCustomClient.VB.vbproj.user | 31 - .../AspNetWebFormsCustomClient.csproj.user | 28 - .../AspNetWebFormsMulticlients.csproj.user | 31 - .../AspWebFormsPopup.csproj.user | 28 - src/CodeProjectForumViewer/packages.config | 4 - .../DropBoxWebForms.csproj.user | 28 - src/DropboxExample/packages.config | 4 - .../GoogleDriveWebForms.csproj.user | 28 - src/Local.testsettings | 13 +- src/MyDropBox/MyDropBox/packages.config | 5 - src/Nemiro.OAuth.sln | 251 +- src/Nemiro.OAuth/AccessToken.cs | 5 +- src/Nemiro.OAuth/ApiDataMapping.cs | 4 +- src/Nemiro.OAuth/ApiDataMappingItem.cs | 5 +- src/Nemiro.OAuth/AuthorizationResult.cs | 5 +- src/Nemiro.OAuth/ClientName.cs | 5 +- src/Nemiro.OAuth/Clients/AmazonClient.cs | 6 +- src/Nemiro.OAuth/Clients/AssemblaClient.cs | 7 +- src/Nemiro.OAuth/Clients/CodeProjectClient.cs | 7 +- src/Nemiro.OAuth/Clients/DropboxClient.cs | 6 +- src/Nemiro.OAuth/Clients/FacebookClient.cs | 5 +- src/Nemiro.OAuth/Clients/FoursquareClient.cs | 5 +- src/Nemiro.OAuth/Clients/GitHubClient.cs | 7 +- src/Nemiro.OAuth/Clients/GoogleClient.cs | 5 +- src/Nemiro.OAuth/Clients/InstagramClient.cs | 7 +- src/Nemiro.OAuth/Clients/LinkedInClient.cs | 6 +- src/Nemiro.OAuth/Clients/LiveClient.cs | 5 +- src/Nemiro.OAuth/Clients/MailRuClient.cs | 4 +- .../Clients/OdnoklassnikiClient.cs | 6 +- src/Nemiro.OAuth/Clients/SoundCloudClient.cs | 6 +- src/Nemiro.OAuth/Clients/SourceForgeClient.cs | 8 +- src/Nemiro.OAuth/Clients/TumblrClient.cs | 7 +- src/Nemiro.OAuth/Clients/TwitterClient.cs | 8 +- src/Nemiro.OAuth/Clients/VkontakteClient.cs | 4 +- src/Nemiro.OAuth/Clients/YahooClient.cs | 7 +- src/Nemiro.OAuth/Clients/YandexClient.cs | 5 +- src/Nemiro.OAuth/Delegates.cs | 14 +- src/Nemiro.OAuth/EmptyResult.cs | 5 +- src/Nemiro.OAuth/Enums/AccessTokenType.cs | 2 +- src/Nemiro.OAuth/Enums/AuthorizationType.cs | 2 +- src/Nemiro.OAuth/Enums/HttpParameterType.cs | 2 +- src/Nemiro.OAuth/Enums/Sex.cs | 2 +- src/Nemiro.OAuth/Enums/SignatureMethods.cs | 2 +- src/Nemiro.OAuth/Enums/UrlEncodingType.cs | 2 +- src/Nemiro.OAuth/ErrorResult.cs | 5 +- .../Exceptions/AccessDeniedException.cs | 5 +- .../Exceptions/AccessTokenException.cs | 5 +- src/Nemiro.OAuth/Exceptions/ApiException.cs | 4 +- .../Exceptions/AuthorizationException.cs | 5 +- .../ClientIsNotRegisteredException.cs | 5 +- .../Exceptions/DuplicateProviderException.cs | 5 +- .../IncompatibleHttpParametersException.cs | 5 +- .../MultipleRequestBodyException.cs | 5 +- .../Exceptions/NullHttpContextException.cs | 5 +- .../Exceptions/RequestException.cs | 5 +- .../Exceptions/UnknownProviderException.cs | 5 +- .../NameValueCollectionExtension.cs | 3 +- src/Nemiro.OAuth/GrantType.cs | 20 +- src/Nemiro.OAuth/HttpAuthorization.cs | 18 +- src/Nemiro.OAuth/HttpFile.cs | 5 +- src/Nemiro.OAuth/HttpFormParameter.cs | 7 +- src/Nemiro.OAuth/HttpParameter.cs | 5 +- src/Nemiro.OAuth/HttpParameterCollection.cs | 233 +- src/Nemiro.OAuth/HttpParameterValue.cs | 94 +- src/Nemiro.OAuth/HttpRequestBody.cs | 6 +- src/Nemiro.OAuth/HttpUrlParameter.cs | 5 +- src/Nemiro.OAuth/Nemiro.OAuth.csproj | 10 +- src/Nemiro.OAuth/Nemiro.OAuth.csproj.user | 6 - src/Nemiro.OAuth/Nemiro.OAuth.snk | Bin 0 -> 596 bytes src/Nemiro.OAuth/OAuth/OAuthAccessToken.cs | 5 +- src/Nemiro.OAuth/OAuth/OAuthAuthorization.cs | 3 +- src/Nemiro.OAuth/OAuth/OAuthClient.cs | 10 +- src/Nemiro.OAuth/OAuth/OAuthRequestToken.cs | 5 +- src/Nemiro.OAuth/OAuth/OAuthSignature.cs | 4 +- src/Nemiro.OAuth/OAuth2/OAuth2AccessToken.cs | 5 +- src/Nemiro.OAuth/OAuth2/OAuth2Client.cs | 6 +- src/Nemiro.OAuth/OAuthBase.cs | 5 +- src/Nemiro.OAuth/OAuthManager.cs | 3 +- src/Nemiro.OAuth/OAuthRequest.cs | 5 +- src/Nemiro.OAuth/OAuthUtility.cs | 305 +- src/Nemiro.OAuth/OAuthWeb.cs | 5 +- src/Nemiro.OAuth/Properties/AssemblyInfo.cs | 6 +- .../Properties/Resources.Designer.cs | 4 +- src/Nemiro.OAuth/Properties/Resources.resx | 2 +- src/Nemiro.OAuth/RequestResult.cs | 8 +- src/Nemiro.OAuth/Resources/Media Kit.txt | 80 - src/Nemiro.OAuth/Resources/aleksey.nemiro.gif | Bin 4584 -> 12324 bytes src/Nemiro.OAuth/Resources/mediakit.md | 97 + src/Nemiro.OAuth/StreamWriteEventArgs.cs | 146 + src/Nemiro.OAuth/UniTypedValue.cs | 7 +- src/Nemiro.OAuth/UniValue.cs | 2 +- src/Nemiro.OAuth/UniValueCollection.cs | 4 +- .../UniValuePropertyDescriptor.cs | 5 +- src/Nemiro.OAuth/UniValueTypeDescriptor.cs | 5 +- src/Nemiro.OAuth/UserInfo.cs | 3 +- src/ReadMe.md | 20 - .../Test.CSharp.AspMvc.csproj.user | 28 - src/Test.CSharp.AspMvc/bin/System.Web.Mvc.dll | Bin 446120 -> 0 bytes .../bin/System.Web.WebPages.dll | Bin 136552 -> 0 bytes .../Test.CSharp.AspWebForms.csproj.user | 28 - src/Test.CSharp.AspWebForms/Web.config | 13 - .../Content/js/MicrosoftAjax.debug.js | 7117 ------------ src/Test.OAuthWeb/Content/js/MicrosoftAjax.js | 6 - .../Content/js/MicrosoftMvcAjax.debug.js | 408 - .../Content/js/MicrosoftMvcAjax.js | 25 - .../js/MicrosoftMvcValidation.debug.js | 883 -- .../Content/js/MicrosoftMvcValidation.js | 55 - src/Test.OAuthWeb/Content/js/jquery-1.5.1.js | 8325 -------------- src/Test.OAuthWeb/Content/js/modernizr-1.7.js | 969 -- .../Content/js/modernizr-1.7.min.js | 10 - src/Test.OAuthWeb/Global.asax | 1 - src/Test.OAuthWeb/Properties/AssemblyInfo.cs | 35 - src/Test.OAuthWeb/Test.OAuthWeb.csproj.user | 31 - .../Views/Shared/Facebook.cshtml | 4 - src/Test.OAuthWeb/Views/Shared/Google.cshtml | 1 - src/Test.OAuthWeb/Views/Shared/Mail.Ru.cshtml | 2 - src/Test.OAuthWeb/Views/Shared/Twitter.cshtml | 2 - src/Test.OAuthWeb/Views/Shared/VK.cshtml | 3 - src/Test.OAuthWeb/Views/Shared/Yandex.cshtml | 4 - src/Test.OAuthWeb/Views/_ViewStart.cshtml | 3 - src/Test.OAuthWeb/bin/System.Web.Mvc.dll | Bin 446120 -> 0 bytes src/Test.OAuthWeb/bin/System.Web.WebPages.dll | Bin 136552 -> 0 bytes src/Test.VB.AspMvc/Test.VB.AspMvc.vbproj.user | 31 - src/Test.VB.AspMvc/Views/Web.config | 58 - src/Test.VB.AspMvc/bin/System.Web.Mvc.dll | Bin 446120 -> 0 bytes .../bin/System.Web.WebPages.dll | Bin 136552 -> 0 bytes .../Test.VB.AspWebForms.vbproj.user | 31 - src/TestProject1/TestProject1.csproj.user | 6 - .../TwitterExample.VB.vbproj.user | 6 - src/TwitterExample.VB/packages.config | 4 - src/WebAndLoadTest/LoadTest1.loadtest | 322 - src/WebAndLoadTest/Properties/AssemblyInfo.cs | 35 - src/WebAndLoadTest/WebAndLoadTest.csproj | 91 - src/WebAndLoadTest/WebTest1.webtest | 30 - .../WebForms35/WebForms35.csproj.user | 28 - 615 files changed, 4192 insertions(+), 58215 deletions(-) rename Release Notes.md => CHANGELOG.md (55%) create mode 100644 README.ru.md delete mode 100644 bin/ReadMe.md delete mode 100644 bin/net35/Nemiro.OAuth.XML delete mode 100644 bin/net35/Nemiro.OAuth.dll delete mode 100644 bin/net40/Nemiro.OAuth.XML delete mode 100644 bin/net40/Nemiro.OAuth.dll delete mode 100644 bin/net45/Nemiro.OAuth.XML delete mode 100644 bin/net45/Nemiro.OAuth.dll delete mode 100644 bin/net451/Nemiro.OAuth.XML delete mode 100644 bin/net451/Nemiro.OAuth.dll create mode 100644 examples/AspNetWebFormsCustomClient.VB/AspNetWebFormsCustomClient.VB.sln rename {src => examples}/AspNetWebFormsCustomClient.VB/AspNetWebFormsCustomClient.VB.vbproj (94%) rename {src => examples}/AspNetWebFormsCustomClient.VB/Default.aspx (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/Default.aspx.designer.vb (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/Default.aspx.vb (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx.designer.vb (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx.vb (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/Global.asax (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/Global.asax.vb (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/My Project/Application.Designer.vb (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/My Project/Application.myapp (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/My Project/AssemblyInfo.vb (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/My Project/MyExtensions/MyWebExtension.vb (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/My Project/Resources.Designer.vb (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/My Project/Resources.resx (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/My Project/Settings.Designer.vb (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/My Project/Settings.settings (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/MyFacebookClient.vb (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/MyTwitterClient.vb (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/Web.Debug.config (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/Web.Release.config (100%) rename {src => examples}/AspNetWebFormsCustomClient.VB/Web.config (100%) rename {src/DropBoxWebForms/DropBoxWebForms => examples/AspNetWebFormsCustomClient.VB}/packages.config (52%) rename {src => examples}/AspNetWebFormsCustomClient/AspNetWebFormsCustomClient.csproj (91%) create mode 100644 examples/AspNetWebFormsCustomClient/AspNetWebFormsCustomClient.sln rename {src => examples}/AspNetWebFormsCustomClient/Default.aspx (100%) rename {src => examples}/AspNetWebFormsCustomClient/Default.aspx.cs (100%) rename {src => examples}/AspNetWebFormsCustomClient/Default.aspx.designer.cs (100%) rename {src => examples}/AspNetWebFormsCustomClient/ExternalLoginResult.aspx (100%) rename {src => examples}/AspNetWebFormsCustomClient/ExternalLoginResult.aspx.cs (100%) rename {src => examples}/AspNetWebFormsCustomClient/ExternalLoginResult.aspx.designer.cs (100%) rename {src => examples}/AspNetWebFormsCustomClient/Global.asax (100%) rename {src => examples}/AspNetWebFormsCustomClient/Global.asax.cs (100%) rename {src => examples}/AspNetWebFormsCustomClient/MyFacebookClient.cs (100%) rename {src => examples}/AspNetWebFormsCustomClient/MyTwitterClient.cs (100%) rename {src => examples}/AspNetWebFormsCustomClient/Properties/AssemblyInfo.cs (100%) rename {src => examples}/AspNetWebFormsCustomClient/Web.Debug.config (100%) rename {src => examples}/AspNetWebFormsCustomClient/Web.Release.config (100%) rename {src => examples}/AspNetWebFormsCustomClient/Web.config (100%) rename {src/GoogleDriveWebForms/GoogleDriveWebForms => examples/AspNetWebFormsCustomClient}/packages.config (52%) rename {src => examples}/AspNetWebFormsMulticlients/AspNetWebFormsMulticlients.csproj (91%) create mode 100644 examples/AspNetWebFormsMulticlients/AspNetWebFormsMulticlients.sln rename {src => examples}/AspNetWebFormsMulticlients/Default.aspx (100%) rename {src => examples}/AspNetWebFormsMulticlients/Default.aspx.cs (100%) rename {src => examples}/AspNetWebFormsMulticlients/Default.aspx.designer.cs (100%) rename {src => examples}/AspNetWebFormsMulticlients/ExternalLoginResult.aspx (100%) rename {src => examples}/AspNetWebFormsMulticlients/ExternalLoginResult.aspx.cs (100%) rename {src => examples}/AspNetWebFormsMulticlients/ExternalLoginResult.aspx.designer.cs (100%) rename {src => examples}/AspNetWebFormsMulticlients/Global.asax (100%) rename {src => examples}/AspNetWebFormsMulticlients/Global.asax.cs (100%) rename {src => examples}/AspNetWebFormsMulticlients/Properties/AssemblyInfo.cs (100%) rename src/AspNetWebFormsMulticlients/ReadMe.md => examples/AspNetWebFormsMulticlients/README.md (100%) rename {src => examples}/AspNetWebFormsMulticlients/RedirectToAuth.aspx (100%) rename {src => examples}/AspNetWebFormsMulticlients/RedirectToAuth.aspx.cs (100%) rename {src => examples}/AspNetWebFormsMulticlients/RedirectToAuth.aspx.designer.cs (100%) rename {src => examples}/AspNetWebFormsMulticlients/Web.Debug.config (100%) rename {src => examples}/AspNetWebFormsMulticlients/Web.Release.config (100%) rename {src => examples}/AspNetWebFormsMulticlients/Web.config (100%) create mode 100644 examples/AspNetWebFormsMulticlients/packages.config rename {src => examples}/AspWebFormsPopup/AspWebFormsPopup.csproj (91%) create mode 100644 examples/AspWebFormsPopup/AspWebFormsPopup.sln rename {src => examples}/AspWebFormsPopup/Default.aspx (100%) rename {src => examples}/AspWebFormsPopup/Default.aspx.cs (100%) rename {src => examples}/AspWebFormsPopup/Default.aspx.designer.cs (100%) rename {src => examples}/AspWebFormsPopup/ExternalLoginResult.aspx (100%) rename {src => examples}/AspWebFormsPopup/ExternalLoginResult.aspx.cs (100%) rename {src => examples}/AspWebFormsPopup/ExternalLoginResult.aspx.designer.cs (100%) rename {src => examples}/AspWebFormsPopup/Global.asax (100%) rename {src => examples}/AspWebFormsPopup/Global.asax.cs (100%) rename {src => examples}/AspWebFormsPopup/Properties/AssemblyInfo.cs (100%) rename src/AspWebFormsPopup/ReadMe.md => examples/AspWebFormsPopup/README.md (100%) rename {src => examples}/AspWebFormsPopup/RedirectToAuth.aspx (100%) rename {src => examples}/AspWebFormsPopup/RedirectToAuth.aspx.cs (100%) rename {src => examples}/AspWebFormsPopup/RedirectToAuth.aspx.designer.cs (100%) rename {src => examples}/AspWebFormsPopup/Web.Debug.config (100%) rename {src => examples}/AspWebFormsPopup/Web.Release.config (100%) rename {src => examples}/AspWebFormsPopup/Web.config (100%) create mode 100644 examples/AspWebFormsPopup/packages.config rename {src => examples}/CodeProjectForumViewer/CodeProjectForumViewer.csproj (88%) create mode 100644 examples/CodeProjectForumViewer/CodeProjectForumViewer.sln rename {src => examples}/CodeProjectForumViewer/LICENSE (100%) rename {src => examples}/CodeProjectForumViewer/MainForm.Designer.cs (100%) rename {src => examples}/CodeProjectForumViewer/MainForm.cs (100%) rename {src => examples}/CodeProjectForumViewer/MainForm.resx (100%) rename {src => examples}/CodeProjectForumViewer/Program.cs (100%) rename {src => examples}/CodeProjectForumViewer/Properties/AssemblyInfo.cs (100%) rename {src => examples}/CodeProjectForumViewer/Properties/Resources.Designer.cs (100%) rename {src => examples}/CodeProjectForumViewer/Properties/Resources.resx (100%) rename {src => examples}/CodeProjectForumViewer/Properties/Settings.Designer.cs (100%) rename {src => examples}/CodeProjectForumViewer/Properties/Settings.settings (100%) rename src/CodeProjectForumViewer/ReadMe.md => examples/CodeProjectForumViewer/README.md (100%) rename {src => examples}/CodeProjectForumViewer/Resources/codeproject.ico (100%) rename {src => examples}/CodeProjectForumViewer/Resources/progress.gif (100%) rename {src => examples}/CodeProjectForumViewer/ThreadViewer.Designer.cs (100%) rename {src => examples}/CodeProjectForumViewer/ThreadViewer.cs (100%) rename {src => examples}/CodeProjectForumViewer/ThreadViewer.resx (100%) rename {src => examples}/CodeProjectForumViewer/app.config (100%) create mode 100644 examples/CodeProjectForumViewer/packages.config rename {src => examples}/CodeProjectForumViewer/preview.jpg (100%) rename {src => examples}/CustomClients/MyClient.cs (100%) rename {src => examples}/CustomClients/MyClient.vb (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/css/Site.css (98%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/css/jquery.jsonview.css (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/images/config.png (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/images/cross.png (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/images/help.png (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/images/preview.png (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/images/processing.gif (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/images/processing2.gif (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/images/tick.png (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/js/jquery-1.5.1-vsdoc.js (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/js/jquery-1.5.1.min.js (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/js/jquery.jsonview.js (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/js/jquery.unobtrusive-ajax.js (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/js/jquery.unobtrusive-ajax.min.js (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/js/jquery.validate-vsdoc.js (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/js/jquery.validate.js (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/js/jquery.validate.min.js (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/js/jquery.validate.unobtrusive.js (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Content/js/jquery.validate.unobtrusive.min.js (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Controllers/ApiController.cs (92%) rename {src/Test.OAuthWeb => examples/DemoSite}/Controllers/CodeProject.cs (91%) rename {src/Test.OAuthWeb => examples/DemoSite}/Controllers/Dropbox.cs (92%) rename {src/Test.OAuthWeb => examples/DemoSite}/Controllers/Facebook.cs (91%) rename {src/Test.OAuthWeb => examples/DemoSite}/Controllers/Google.cs (91%) rename {src/Test.OAuthWeb => examples/DemoSite}/Controllers/HomeController.cs (88%) rename {src/Test.OAuthWeb => examples/DemoSite}/Controllers/MailRu.cs (93%) rename {src/Test.OAuthWeb => examples/DemoSite}/Controllers/Twitter.cs (93%) rename {src/Test.OAuthWeb => examples/DemoSite}/Controllers/VK.cs (93%) rename {src/Test.OAuthWeb => examples/DemoSite}/Controllers/Yandex.cs (98%) rename src/Test.OAuthWeb/Test.OAuthWeb.csproj => examples/DemoSite/DemoOAuth.csproj (50%) create mode 100644 examples/DemoSite/DemoOAuth.sln create mode 100644 examples/DemoSite/Global.asax rename {src/Test.OAuthWeb => examples/DemoSite}/Global.asax.cs (90%) create mode 100644 examples/DemoSite/Images.Designer.cs rename {src/Test.Resources => examples/DemoSite}/Images.resx (100%) create mode 100644 examples/DemoSite/Properties/AssemblyInfo.cs rename src/Test.OAuthWeb/ReadMe.md => examples/DemoSite/README.md (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/amazon.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/amazon100.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/assembla.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/codeproject (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/dropbox.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/empty.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/error.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/facebook100.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/foursquare.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/github100.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/google100.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/instagram.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/linkedin.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/live.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/mail.ru100.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/odnoklassniki100.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/soundcloud.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/sourceforge.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/tumblr.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/twitter100.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/vk100.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/yahoo.dat (100%) rename {src/Test.Resources => examples/DemoSite}/Resources/yandex100.dat (100%) create mode 100644 examples/DemoSite/Strings.Designer.cs create mode 100644 examples/DemoSite/Strings.resx rename {src/Test.Resources => examples/DemoSite}/Strings.ru.Designer.cs (100%) create mode 100644 examples/DemoSite/Strings.ru.resx rename {src/Test.OAuthWeb => examples/DemoSite}/Views/Home/Index.cshtml (88%) rename {src/Test.OAuthWeb => examples/DemoSite}/Views/Home/Result.cshtml (80%) rename {src/Test.OAuthWeb => examples/DemoSite}/Views/Shared/CodeProject.cshtml (100%) rename {src/Test.OAuthWeb => examples/DemoSite}/Views/Shared/Dropbox.cshtml (100%) rename {src/Test.CSharp.AspMvc => examples/DemoSite}/Views/Shared/Error.cshtml (100%) create mode 100644 examples/DemoSite/Views/Shared/Facebook.cshtml create mode 100644 examples/DemoSite/Views/Shared/Google.cshtml create mode 100644 examples/DemoSite/Views/Shared/Mail.Ru.cshtml create mode 100644 examples/DemoSite/Views/Shared/Twitter.cshtml create mode 100644 examples/DemoSite/Views/Shared/VK.cshtml create mode 100644 examples/DemoSite/Views/Shared/Yandex.cshtml rename {src/Test.OAuthWeb => examples/DemoSite}/Views/Shared/_Layout.cshtml (97%) create mode 100644 examples/DemoSite/Views/web.config rename {src/Test.VB.AspWebForms => examples/DemoSite}/Web.Debug.config (69%) rename {src/Test.VB.AspWebForms => examples/DemoSite}/Web.Release.config (70%) rename {src/Test.OAuthWeb => examples/DemoSite}/Web.config (65%) create mode 100644 examples/DemoSite/packages.config rename {src/Test.OAuthWeb => examples/DemoSite}/receiver.html (100%) rename {src/DropBoxWebForms => examples}/DropBoxWebForms/Default.aspx (100%) rename {src/DropBoxWebForms => examples}/DropBoxWebForms/Default.aspx.cs (100%) rename {src/DropBoxWebForms => examples}/DropBoxWebForms/Default.aspx.designer.cs (100%) rename {src/DropBoxWebForms => examples}/DropBoxWebForms/DropBoxWebForms.csproj (79%) rename {src => examples}/DropBoxWebForms/DropBoxWebForms.sln (76%) rename {src/DropBoxWebForms => examples}/DropBoxWebForms/ExternalLoginResult.aspx (100%) rename {src/DropBoxWebForms => examples}/DropBoxWebForms/ExternalLoginResult.aspx.cs (100%) rename {src/DropBoxWebForms => examples}/DropBoxWebForms/ExternalLoginResult.aspx.designer.cs (100%) rename {src/DropBoxWebForms => examples}/DropBoxWebForms/Global.asax (100%) rename {src/DropBoxWebForms => examples}/DropBoxWebForms/Global.asax.cs (100%) rename {src/DropBoxWebForms => examples}/DropBoxWebForms/Properties/AssemblyInfo.cs (100%) rename {src/DropBoxWebForms => examples}/DropBoxWebForms/Web.Debug.config (100%) rename {src/DropBoxWebForms => examples}/DropBoxWebForms/Web.Release.config (100%) rename {src/DropBoxWebForms => examples}/DropBoxWebForms/Web.config (100%) create mode 100644 examples/DropBoxWebForms/packages.config rename {src => examples}/DropboxExample/Download.Designer.cs (62%) rename {src => examples}/DropboxExample/Download.cs (97%) rename {src => examples}/DropboxExample/Download.resx (100%) rename {src => examples}/DropboxExample/DropboxExample.csproj (90%) create mode 100644 examples/DropboxExample/DropboxExample.sln rename {src => examples}/DropboxExample/InputBox.Designer.cs (99%) rename {src => examples}/DropboxExample/InputBox.cs (96%) rename {src => examples}/DropboxExample/InputBox.resx (100%) rename {src => examples}/DropboxExample/LICENSE (100%) rename {src => examples}/DropboxExample/MainForm.Designer.cs (99%) rename {src => examples}/DropboxExample/MainForm.cs (98%) rename {src => examples}/DropboxExample/MainForm.resx (100%) rename {src => examples}/DropboxExample/Program.cs (95%) rename {src => examples}/DropboxExample/Properties/AssemblyInfo.cs (92%) rename {src => examples}/DropboxExample/Properties/Resources.Designer.cs (100%) rename {src => examples}/DropboxExample/Properties/Resources.resx (100%) rename {src => examples}/DropboxExample/Properties/Settings.Designer.cs (100%) rename {src => examples}/DropboxExample/Properties/Settings.settings (100%) rename src/DropboxExample/ReadMe.md => examples/DropboxExample/README.md (100%) rename {src => examples}/DropboxExample/Resources/alert.png (100%) rename {src => examples}/DropboxExample/Resources/bin.png (100%) rename {src => examples}/DropboxExample/Resources/disk.png (100%) rename {src => examples}/DropboxExample/Resources/disk__plus.png (100%) rename {src => examples}/DropboxExample/Resources/document__pencil.png (100%) rename {src => examples}/DropboxExample/Resources/error.png (100%) rename {src => examples}/DropboxExample/Resources/folder__plus.png (100%) rename {src => examples}/DropboxExample/Resources/loader1.gif (100%) rename {src => examples}/DropboxExample/Resources/loader2.gif (100%) rename {src => examples}/DropboxExample/Resources/success.png (100%) rename {src => examples}/DropboxExample/Upload.Designer.cs (52%) rename {src => examples}/DropboxExample/Upload.cs (61%) rename {src => examples}/DropboxExample/Upload.resx (100%) rename {src => examples}/DropboxExample/app.config (61%) rename {src => examples}/DropboxExample/dropbox.ico (100%) create mode 100644 examples/DropboxExample/packages.config rename {src => examples}/DropboxExample/preview.png (100%) rename {src/GoogleDriveWebForms => examples}/GoogleDriveWebForms/Default.aspx (100%) rename {src/GoogleDriveWebForms => examples}/GoogleDriveWebForms/Default.aspx.cs (67%) rename {src/GoogleDriveWebForms => examples}/GoogleDriveWebForms/Default.aspx.designer.cs (100%) rename {src/GoogleDriveWebForms => examples}/GoogleDriveWebForms/ExternalLoginResult.aspx (100%) rename {src/GoogleDriveWebForms => examples}/GoogleDriveWebForms/ExternalLoginResult.aspx.cs (100%) rename {src/GoogleDriveWebForms => examples}/GoogleDriveWebForms/ExternalLoginResult.aspx.designer.cs (100%) rename {src/GoogleDriveWebForms => examples}/GoogleDriveWebForms/Global.asax (100%) rename {src/GoogleDriveWebForms => examples}/GoogleDriveWebForms/Global.asax.cs (100%) rename {src/GoogleDriveWebForms => examples}/GoogleDriveWebForms/GoogleDriveWebForms.csproj (79%) rename {src => examples}/GoogleDriveWebForms/GoogleDriveWebForms.sln (75%) rename {src/GoogleDriveWebForms => examples}/GoogleDriveWebForms/Properties/AssemblyInfo.cs (100%) rename {src/GoogleDriveWebForms => examples}/GoogleDriveWebForms/Web.Debug.config (100%) rename {src/GoogleDriveWebForms => examples}/GoogleDriveWebForms/Web.Release.config (100%) create mode 100644 examples/GoogleDriveWebForms/Web.config create mode 100644 examples/GoogleDriveWebForms/packages.config create mode 100644 examples/GrantTypeClientCredentials/GrantTypeClientCredentials.sln rename {src => examples}/GrantTypeClientCredentials/GrantTypeClientCredentials.vbproj (93%) rename {src => examples}/GrantTypeClientCredentials/Module1.vb (100%) rename {src => examples}/GrantTypeClientCredentials/My Project/Application.Designer.vb (100%) rename {src => examples}/GrantTypeClientCredentials/My Project/Application.myapp (100%) rename {src => examples}/GrantTypeClientCredentials/My Project/AssemblyInfo.vb (100%) rename {src => examples}/GrantTypeClientCredentials/My Project/Resources.Designer.vb (100%) rename {src => examples}/GrantTypeClientCredentials/My Project/Resources.resx (100%) rename {src => examples}/GrantTypeClientCredentials/My Project/Settings.Designer.vb (100%) rename {src => examples}/GrantTypeClientCredentials/My Project/Settings.settings (100%) rename {src => examples}/GrantTypeClientCredentials/app.config (100%) create mode 100644 examples/GrantTypeClientCredentials/packages.config rename {src/MyDropBox => examples}/MyDropBox/App.config (65%) rename {src/MyDropBox => examples}/MyDropBox/Form1.Designer.cs (100%) rename {src/MyDropBox => examples}/MyDropBox/Form1.cs (71%) rename {src/MyDropBox => examples}/MyDropBox/Form1.resx (100%) rename {src/MyDropBox => examples}/MyDropBox/MyDropBox.csproj (87%) rename {src => examples}/MyDropBox/MyDropBox.sln (92%) rename {src/MyDropBox => examples}/MyDropBox/Program.cs (81%) rename {src/MyDropBox => examples}/MyDropBox/Properties/AssemblyInfo.cs (100%) rename {src/MyDropBox => examples}/MyDropBox/Properties/Resources.Designer.cs (100%) rename {src/MyDropBox => examples}/MyDropBox/Properties/Resources.resx (100%) rename {src/MyDropBox => examples}/MyDropBox/Properties/Settings.Designer.cs (100%) rename {src/MyDropBox => examples}/MyDropBox/Properties/Settings.settings (100%) rename {src => examples}/MyDropBox/Watch on YouTube.url (100%) create mode 100644 examples/MyDropBox/packages.config rename {src => examples/Test}/Test.CSharp.AspMvc/Content/Site.css (100%) rename {src => examples/Test}/Test.CSharp.AspMvc/Controllers/HomeController.cs (100%) rename {src => examples/Test}/Test.CSharp.AspMvc/Global.asax (100%) rename {src => examples/Test}/Test.CSharp.AspMvc/Global.asax.cs (100%) rename {src => examples/Test}/Test.CSharp.AspMvc/Properties/AssemblyInfo.cs (100%) rename {src => examples/Test}/Test.CSharp.AspMvc/Test.CSharp.AspMvc.csproj (75%) rename {src => examples/Test}/Test.CSharp.AspMvc/Views/Home/ExternalLoginResult.cshtml (100%) rename {src => examples/Test}/Test.CSharp.AspMvc/Views/Home/Index.cshtml (100%) rename {src/Test.OAuthWeb => examples/Test/Test.CSharp.AspMvc}/Views/Shared/Error.cshtml (100%) rename {src => examples/Test}/Test.CSharp.AspMvc/Views/Shared/_Layout.cshtml (100%) rename {src => examples/Test}/Test.CSharp.AspMvc/Views/Web.config (100%) rename {src => examples/Test}/Test.CSharp.AspMvc/Views/_ViewStart.cshtml (100%) rename {src => examples/Test}/Test.CSharp.AspMvc/Web.Debug.config (100%) rename {src => examples/Test}/Test.CSharp.AspMvc/Web.Release.config (100%) rename {src => examples/Test}/Test.CSharp.AspMvc/Web.config (69%) create mode 100644 examples/Test/Test.CSharp.AspMvc/packages.config rename {src => examples/Test}/Test.CSharp.AspWebForms/Default.aspx (100%) rename {src => examples/Test}/Test.CSharp.AspWebForms/Default.aspx.cs (100%) rename {src => examples/Test}/Test.CSharp.AspWebForms/Default.aspx.designer.cs (100%) rename {src => examples/Test}/Test.CSharp.AspWebForms/ExternalLoginResult.aspx (100%) rename {src => examples/Test}/Test.CSharp.AspWebForms/ExternalLoginResult.aspx.cs (100%) rename {src => examples/Test}/Test.CSharp.AspWebForms/ExternalLoginResult.aspx.designer.cs (100%) rename {src => examples/Test}/Test.CSharp.AspWebForms/Global.asax (100%) rename {src => examples/Test}/Test.CSharp.AspWebForms/Global.asax.cs (100%) rename {src => examples/Test}/Test.CSharp.AspWebForms/Icon.ashx (100%) rename {src => examples/Test}/Test.CSharp.AspWebForms/Icon.ashx.cs (100%) rename {src => examples/Test}/Test.CSharp.AspWebForms/Properties/AssemblyInfo.cs (100%) rename {src => examples/Test}/Test.CSharp.AspWebForms/Site.css (100%) rename {src => examples/Test}/Test.CSharp.AspWebForms/Test.CSharp.AspWebForms.csproj (91%) rename {src => examples/Test}/Test.CSharp.AspWebForms/Web.Debug.config (100%) rename {src => examples/Test}/Test.CSharp.AspWebForms/Web.Release.config (100%) rename {src/GoogleDriveWebForms/GoogleDriveWebForms => examples/Test/Test.CSharp.AspWebForms}/Web.config (100%) create mode 100644 examples/Test/Test.CSharp.AspWebForms/packages.config rename {src => examples/Test}/Test.CSharp.WinForms/Form1.Designer.cs (100%) rename {src => examples/Test}/Test.CSharp.WinForms/Form1.cs (100%) rename {src => examples/Test}/Test.CSharp.WinForms/Form1.resx (100%) rename {src => examples/Test}/Test.CSharp.WinForms/Form2.Designer.cs (100%) rename {src => examples/Test}/Test.CSharp.WinForms/Form2.cs (100%) rename {src => examples/Test}/Test.CSharp.WinForms/Form2.resx (100%) rename {src => examples/Test}/Test.CSharp.WinForms/Program.cs (100%) rename {src => examples/Test}/Test.CSharp.WinForms/Properties/AssemblyInfo.cs (100%) rename {src => examples/Test}/Test.CSharp.WinForms/Properties/Resources.Designer.cs (100%) rename {src => examples/Test}/Test.CSharp.WinForms/Properties/Resources.resx (100%) rename {src => examples/Test}/Test.CSharp.WinForms/Properties/Settings.Designer.cs (100%) rename {src => examples/Test}/Test.CSharp.WinForms/Properties/Settings.settings (100%) rename {src => examples/Test}/Test.CSharp.WinForms/Test.CSharp.WinForms.csproj (93%) rename {src => examples/Test}/Test.CSharp.WinForms/VkontakteFriends.Designer.cs (100%) rename {src => examples/Test}/Test.CSharp.WinForms/VkontakteFriends.cs (100%) rename {src => examples/Test}/Test.CSharp.WinForms/VkontakteFriends.resx (100%) rename {src => examples/Test}/Test.CSharp.WinForms/app.config (100%) create mode 100644 examples/Test/Test.CSharp.WinForms/packages.config rename {src => examples/Test}/Test.Resources/Images.Designer.cs (100%) create mode 100644 examples/Test/Test.Resources/Images.resx rename {src => examples/Test}/Test.Resources/Properties/AssemblyInfo.cs (100%) rename {src => examples/Test}/Test.Resources/ReadMe.txt (100%) create mode 100644 examples/Test/Test.Resources/Resources/amazon.dat create mode 100644 examples/Test/Test.Resources/Resources/amazon100.dat create mode 100644 examples/Test/Test.Resources/Resources/assembla.dat create mode 100644 examples/Test/Test.Resources/Resources/codeproject create mode 100644 examples/Test/Test.Resources/Resources/dropbox.dat create mode 100644 examples/Test/Test.Resources/Resources/empty.dat create mode 100644 examples/Test/Test.Resources/Resources/error.dat create mode 100644 examples/Test/Test.Resources/Resources/facebook100.dat create mode 100644 examples/Test/Test.Resources/Resources/foursquare.dat create mode 100644 examples/Test/Test.Resources/Resources/github100.dat create mode 100644 examples/Test/Test.Resources/Resources/google100.dat create mode 100644 examples/Test/Test.Resources/Resources/instagram.dat create mode 100644 examples/Test/Test.Resources/Resources/linkedin.dat create mode 100644 examples/Test/Test.Resources/Resources/live.dat create mode 100644 examples/Test/Test.Resources/Resources/mail.ru100.dat create mode 100644 examples/Test/Test.Resources/Resources/odnoklassniki100.dat create mode 100644 examples/Test/Test.Resources/Resources/soundcloud.dat create mode 100644 examples/Test/Test.Resources/Resources/sourceforge.dat create mode 100644 examples/Test/Test.Resources/Resources/tumblr.dat create mode 100644 examples/Test/Test.Resources/Resources/twitter100.dat create mode 100644 examples/Test/Test.Resources/Resources/vk100.dat create mode 100644 examples/Test/Test.Resources/Resources/yahoo.dat create mode 100644 examples/Test/Test.Resources/Resources/yandex100.dat rename {src => examples/Test}/Test.Resources/Strings.Designer.cs (100%) rename {src => examples/Test}/Test.Resources/Strings.resx (100%) create mode 100644 examples/Test/Test.Resources/Strings.ru.Designer.cs rename {src => examples/Test}/Test.Resources/Strings.ru.resx (100%) rename {src => examples/Test}/Test.Resources/Test.Resources.csproj (93%) create mode 100644 examples/Test/Test.Resources/packages.config rename {src => examples/Test}/Test.VB.AspMvc/Content/Site.css (100%) rename {src => examples/Test}/Test.VB.AspMvc/Controllers/HomeController.vb (100%) rename {src => examples/Test}/Test.VB.AspMvc/Global.asax (100%) rename {src => examples/Test}/Test.VB.AspMvc/Global.asax.vb (100%) rename {src => examples/Test}/Test.VB.AspMvc/My Project/Application.Designer.vb (100%) rename {src => examples/Test}/Test.VB.AspMvc/My Project/Application.myapp (100%) rename {src => examples/Test}/Test.VB.AspMvc/My Project/AssemblyInfo.vb (100%) rename {src => examples/Test}/Test.VB.AspMvc/My Project/Resources.Designer.vb (100%) rename {src => examples/Test}/Test.VB.AspMvc/My Project/Resources.resx (100%) rename {src => examples/Test}/Test.VB.AspMvc/My Project/Settings.Designer.vb (100%) rename {src => examples/Test}/Test.VB.AspMvc/My Project/Settings.settings (100%) rename {src => examples/Test}/Test.VB.AspMvc/Test.VB.AspMvc.vbproj (81%) rename {src => examples/Test}/Test.VB.AspMvc/Views/Home/ExternalLoginResult.vbhtml (100%) rename {src => examples/Test}/Test.VB.AspMvc/Views/Home/Index.vbhtml (100%) rename {src => examples/Test}/Test.VB.AspMvc/Views/Shared/Error.vbhtml (100%) rename {src => examples/Test}/Test.VB.AspMvc/Views/Shared/_Layout.vbhtml (100%) rename {src/Test.OAuthWeb => examples/Test/Test.VB.AspMvc}/Views/Web.config (100%) rename {src => examples/Test}/Test.VB.AspMvc/Views/_ViewStart.vbhtml (100%) rename {src/Test.OAuthWeb => examples/Test/Test.VB.AspMvc}/Web.Debug.config (100%) rename {src/Test.OAuthWeb => examples/Test/Test.VB.AspMvc}/Web.Release.config (100%) rename {src => examples/Test}/Test.VB.AspMvc/Web.config (69%) create mode 100644 examples/Test/Test.VB.AspMvc/packages.config rename {src => examples/Test}/Test.VB.AspWebForms/Default.aspx (100%) rename {src => examples/Test}/Test.VB.AspWebForms/Default.aspx.designer.vb (100%) rename {src => examples/Test}/Test.VB.AspWebForms/Default.aspx.vb (100%) rename {src => examples/Test}/Test.VB.AspWebForms/ExternalLoginResult.aspx (100%) rename {src => examples/Test}/Test.VB.AspWebForms/ExternalLoginResult.aspx.designer.vb (100%) rename {src => examples/Test}/Test.VB.AspWebForms/ExternalLoginResult.aspx.vb (100%) rename {src => examples/Test}/Test.VB.AspWebForms/Global.asax (100%) rename {src => examples/Test}/Test.VB.AspWebForms/Global.asax.vb (100%) rename {src => examples/Test}/Test.VB.AspWebForms/Icon.ashx (100%) rename {src => examples/Test}/Test.VB.AspWebForms/Icon.ashx.vb (100%) rename {src => examples/Test}/Test.VB.AspWebForms/My Project/Application.Designer.vb (100%) rename {src => examples/Test}/Test.VB.AspWebForms/My Project/Application.myapp (100%) rename {src => examples/Test}/Test.VB.AspWebForms/My Project/AssemblyInfo.vb (100%) rename {src => examples/Test}/Test.VB.AspWebForms/My Project/MyExtensions/MyWebExtension.vb (100%) rename {src => examples/Test}/Test.VB.AspWebForms/My Project/Resources.Designer.vb (100%) rename {src => examples/Test}/Test.VB.AspWebForms/My Project/Resources.resx (100%) rename {src => examples/Test}/Test.VB.AspWebForms/My Project/Settings.Designer.vb (100%) rename {src => examples/Test}/Test.VB.AspWebForms/My Project/Settings.settings (100%) rename {src => examples/Test}/Test.VB.AspWebForms/Site.css (100%) rename {src => examples/Test}/Test.VB.AspWebForms/Test.VB.AspWebForms.vbproj (94%) rename {src/Test.VB.AspMvc => examples/Test/Test.VB.AspWebForms}/Web.Debug.config (100%) rename {src/Test.VB.AspMvc => examples/Test/Test.VB.AspWebForms}/Web.Release.config (100%) rename {src => examples/Test}/Test.VB.AspWebForms/Web.config (100%) create mode 100644 examples/Test/Test.VB.AspWebForms/packages.config rename {src => examples/Test}/Test.VB.WinForms/App.config (100%) rename {src => examples/Test}/Test.VB.WinForms/Form1.Designer.vb (100%) rename {src => examples/Test}/Test.VB.WinForms/Form1.resx (100%) rename {src => examples/Test}/Test.VB.WinForms/Form1.vb (100%) rename {src => examples/Test}/Test.VB.WinForms/Form2.Designer.vb (100%) rename {src => examples/Test}/Test.VB.WinForms/Form2.resx (100%) rename {src => examples/Test}/Test.VB.WinForms/Form2.vb (100%) rename {src => examples/Test}/Test.VB.WinForms/My Project/Application.Designer.vb (100%) rename {src => examples/Test}/Test.VB.WinForms/My Project/Application.myapp (100%) rename {src => examples/Test}/Test.VB.WinForms/My Project/AssemblyInfo.vb (100%) rename {src => examples/Test}/Test.VB.WinForms/My Project/Resources.Designer.vb (100%) rename {src => examples/Test}/Test.VB.WinForms/My Project/Resources.resx (100%) rename {src => examples/Test}/Test.VB.WinForms/My Project/Settings.Designer.vb (100%) rename {src => examples/Test}/Test.VB.WinForms/My Project/Settings.settings (100%) rename {src => examples/Test}/Test.VB.WinForms/Test.VB.WinForms.vbproj (94%) rename {src => examples/Test}/Test.VB.WinForms/VkontakteFriends.Designer.vb (100%) rename {src => examples/Test}/Test.VB.WinForms/VkontakteFriends.resx (100%) rename {src => examples/Test}/Test.VB.WinForms/VkontakteFriends.vb (100%) create mode 100644 examples/Test/Test.VB.WinForms/packages.config create mode 100644 examples/Test/Test.sln rename {src => examples}/TwitterExample.VB/App.config (100%) rename {src => examples}/TwitterExample.VB/LICENSE (100%) rename {src => examples}/TwitterExample.VB/MainForm.Designer.vb (99%) rename {src => examples}/TwitterExample.VB/MainForm.resx (100%) rename {src => examples}/TwitterExample.VB/MainForm.vb (96%) rename {src => examples}/TwitterExample.VB/My Project/Application.Designer.vb (100%) rename {src => examples}/TwitterExample.VB/My Project/Application.myapp (100%) rename {src => examples}/TwitterExample.VB/My Project/AssemblyInfo.vb (100%) rename {src => examples}/TwitterExample.VB/My Project/Resources.Designer.vb (100%) rename {src => examples}/TwitterExample.VB/My Project/Resources.resx (100%) rename {src => examples}/TwitterExample.VB/My Project/Settings.Designer.vb (100%) rename {src => examples}/TwitterExample.VB/My Project/Settings.settings (100%) rename {src => examples}/TwitterExample.VB/My Project/app.manifest (100%) rename src/TwitterExample.VB/ReadMe.md => examples/TwitterExample.VB/README.md (100%) rename {src => examples}/TwitterExample.VB/Resources/alert.png (100%) rename {src => examples}/TwitterExample.VB/Resources/error.png (100%) rename {src => examples}/TwitterExample.VB/Resources/loader1.gif (100%) rename {src => examples}/TwitterExample.VB/Resources/loader2.gif (100%) rename {src => examples}/TwitterExample.VB/Resources/success.png (100%) create mode 100644 examples/TwitterExample.VB/TwitterExample.VB.sln rename {src => examples}/TwitterExample.VB/TwitterExample.VB.vbproj (91%) rename {src => examples}/TwitterExample.VB/TwitterItem.Designer.vb (98%) rename {src => examples}/TwitterExample.VB/TwitterItem.resx (100%) rename {src => examples}/TwitterExample.VB/TwitterItem.vb (97%) create mode 100644 examples/TwitterExample.VB/packages.config rename {src => examples}/TwitterExample.VB/preview.png (100%) rename {src => examples}/TwitterExample.VB/twitter.ico (100%) rename {src/WebForms35 => examples}/WebForms35/Default.aspx (100%) rename {src/WebForms35 => examples}/WebForms35/Default.aspx.cs (100%) rename {src/WebForms35 => examples}/WebForms35/Default.aspx.designer.cs (100%) rename {src/WebForms35 => examples}/WebForms35/ExternalLoginResult.aspx (100%) rename {src/WebForms35 => examples}/WebForms35/ExternalLoginResult.aspx.cs (100%) rename {src/WebForms35 => examples}/WebForms35/ExternalLoginResult.aspx.designer.cs (100%) rename {src/WebForms35 => examples}/WebForms35/Global.asax (100%) rename {src/WebForms35 => examples}/WebForms35/Global.asax.cs (100%) rename {src/WebForms35 => examples}/WebForms35/Properties/AssemblyInfo.cs (100%) rename {src/WebForms35 => examples}/WebForms35/Web.Debug.config (100%) rename {src/WebForms35 => examples}/WebForms35/Web.Release.config (100%) rename {src/WebForms35 => examples}/WebForms35/Web.config (100%) rename {src/WebForms35 => examples}/WebForms35/WebForms35.csproj (96%) rename {src => examples}/WebForms35/WebForms35.sln (92%) rename {src/WebForms35 => examples}/WebForms35/packages.config (52%) delete mode 100644 src/AspNetWebFormsCustomClient.VB/AspNetWebFormsCustomClient.VB.vbproj.user delete mode 100644 src/AspNetWebFormsCustomClient/AspNetWebFormsCustomClient.csproj.user delete mode 100644 src/AspNetWebFormsMulticlients/AspNetWebFormsMulticlients.csproj.user delete mode 100644 src/AspWebFormsPopup/AspWebFormsPopup.csproj.user delete mode 100644 src/CodeProjectForumViewer/packages.config delete mode 100644 src/DropBoxWebForms/DropBoxWebForms/DropBoxWebForms.csproj.user delete mode 100644 src/DropboxExample/packages.config delete mode 100644 src/GoogleDriveWebForms/GoogleDriveWebForms/GoogleDriveWebForms.csproj.user delete mode 100644 src/MyDropBox/MyDropBox/packages.config delete mode 100644 src/Nemiro.OAuth/Nemiro.OAuth.csproj.user create mode 100644 src/Nemiro.OAuth/Nemiro.OAuth.snk delete mode 100644 src/Nemiro.OAuth/Resources/Media Kit.txt create mode 100644 src/Nemiro.OAuth/Resources/mediakit.md create mode 100644 src/Nemiro.OAuth/StreamWriteEventArgs.cs delete mode 100644 src/ReadMe.md delete mode 100644 src/Test.CSharp.AspMvc/Test.CSharp.AspMvc.csproj.user delete mode 100644 src/Test.CSharp.AspMvc/bin/System.Web.Mvc.dll delete mode 100644 src/Test.CSharp.AspMvc/bin/System.Web.WebPages.dll delete mode 100644 src/Test.CSharp.AspWebForms/Test.CSharp.AspWebForms.csproj.user delete mode 100644 src/Test.CSharp.AspWebForms/Web.config delete mode 100644 src/Test.OAuthWeb/Content/js/MicrosoftAjax.debug.js delete mode 100644 src/Test.OAuthWeb/Content/js/MicrosoftAjax.js delete mode 100644 src/Test.OAuthWeb/Content/js/MicrosoftMvcAjax.debug.js delete mode 100644 src/Test.OAuthWeb/Content/js/MicrosoftMvcAjax.js delete mode 100644 src/Test.OAuthWeb/Content/js/MicrosoftMvcValidation.debug.js delete mode 100644 src/Test.OAuthWeb/Content/js/MicrosoftMvcValidation.js delete mode 100644 src/Test.OAuthWeb/Content/js/jquery-1.5.1.js delete mode 100644 src/Test.OAuthWeb/Content/js/modernizr-1.7.js delete mode 100644 src/Test.OAuthWeb/Content/js/modernizr-1.7.min.js delete mode 100644 src/Test.OAuthWeb/Global.asax delete mode 100644 src/Test.OAuthWeb/Properties/AssemblyInfo.cs delete mode 100644 src/Test.OAuthWeb/Test.OAuthWeb.csproj.user delete mode 100644 src/Test.OAuthWeb/Views/Shared/Facebook.cshtml delete mode 100644 src/Test.OAuthWeb/Views/Shared/Google.cshtml delete mode 100644 src/Test.OAuthWeb/Views/Shared/Mail.Ru.cshtml delete mode 100644 src/Test.OAuthWeb/Views/Shared/Twitter.cshtml delete mode 100644 src/Test.OAuthWeb/Views/Shared/VK.cshtml delete mode 100644 src/Test.OAuthWeb/Views/Shared/Yandex.cshtml delete mode 100644 src/Test.OAuthWeb/Views/_ViewStart.cshtml delete mode 100644 src/Test.OAuthWeb/bin/System.Web.Mvc.dll delete mode 100644 src/Test.OAuthWeb/bin/System.Web.WebPages.dll delete mode 100644 src/Test.VB.AspMvc/Test.VB.AspMvc.vbproj.user delete mode 100644 src/Test.VB.AspMvc/Views/Web.config delete mode 100644 src/Test.VB.AspMvc/bin/System.Web.Mvc.dll delete mode 100644 src/Test.VB.AspMvc/bin/System.Web.WebPages.dll delete mode 100644 src/Test.VB.AspWebForms/Test.VB.AspWebForms.vbproj.user delete mode 100644 src/TestProject1/TestProject1.csproj.user delete mode 100644 src/TwitterExample.VB/TwitterExample.VB.vbproj.user delete mode 100644 src/TwitterExample.VB/packages.config delete mode 100644 src/WebAndLoadTest/LoadTest1.loadtest delete mode 100644 src/WebAndLoadTest/Properties/AssemblyInfo.cs delete mode 100644 src/WebAndLoadTest/WebAndLoadTest.csproj delete mode 100644 src/WebAndLoadTest/WebTest1.webtest delete mode 100644 src/WebForms35/WebForms35/WebForms35.csproj.user diff --git a/Release Notes.md b/CHANGELOG.md similarity index 55% rename from Release Notes.md rename to CHANGELOG.md index dca6473..38f0c1b 100644 --- a/Release Notes.md +++ b/CHANGELOG.md @@ -1,115 +1,153 @@ -### Nemiro.OAuth Release Notes +# Change Log This document summarizes the changes in recent releases. -#### v1.10 (June 21, 2015) +## [v1.11] - unreleased + +This release includes minor fixes and enhancements. + +### Added +* Added parameter names encoding; +* Added the ability to upload large files; +* Strong name. + +### Thanks +* [Nicola Bizzoca](https://github.com/nico159) +* [Michael Collins](https://github.com/mfcollins3) + +## [v1.10] - 2015-06-21 This version includes fixes for .NET 3.5 and common enhancements. -* Fixed bug in the WriteToRequestStream for .NET Framework 3.5; +### Added +* Added the ability to use any multipart requests (not only `multipart/form-data`); + +### Removed +* Removed the obsolete overload of the `GetUserInfo`. + +### Fixed +* Fixed bug in the `WriteToRequestStream` for .NET Framework 3.5; * Fixed error: "Inheritance security rules violated while overriding member: UniValue.GetObjectData...". An error was detected in projects .NET Framework 3.5; * Fixed client for LinkedIn (updated default scope); -* Added the ability to use any multipart requests (not only multipart/form-data); -* Removed the obsolete overload of the GetUserInfo. - -##### Thanks: +### Thanks * [Ramil Khazhiev](https://github.com/RamilKhazhiev) * [Asi Nehrim](http://www.youtube.com/channel/UC6dAAoRUxMGBR3FwP_P9vAA) * [CodeProject Member 11728803](http://www.codeproject.com/script/Membership/View.aspx?mid=11728803) -#### v1.9 (March 19, 2015) +## [v1.9] - 2015-03-19 This version includes fixes and enhancements. +### Added * In the method GetUserInfo added ability to specify an access token; -* In the web methods of the OAuthUtility class added ability to specify an access token; +* In the web methods of the `OAuthUtility` class added ability to specify an access token; +* Implemented refreshing and revoking an access token for providers that support it. + +### Changed +* Updated URLs in the `GoogleClient`; +* Reworked the `AccessToken` class; + +### Fixed * Fixed JSON: * single quotes replaced by double; * names are placed in quotation marks; * added encoding special characters, and unicode characters; * fixed the decimal separator for numbers. * Fixed bug with overwriting the query parameters in obtaining authorization address; -* Fixed UserInfo mapper for LinkedIn; -* Fixed typo (internal): Requet -> Requests; -* Updated URLs in the GoogleClient; -* Reworked the AccessToken class; -* Implemented refreshing and revoking an access token for providers that support it. - -##### Thanks: +* Fixed `UserInfo` mapper for LinkedIn; +* Fixed typo (internal): `Requet` -> `Requests`; +### Thanks * [Mike Norgate](https://github.com/oesoftware) -* [sdbarron](https://github.com/sdbarron) +* [Steve Barron](https://github.com/sdbarron) -#### v1.8 (March 8, 2015) +## [v1.8] - 2015-03-08 This version includes enhancements for customization. -* Fixed bug with DefaultScope and Scope; +### Added * Added the ability to register multiple client with the same name; * Added decoding html-entities in the processing of a callback address, if provider, for some reason, perform encoding (potential problem is detected in Foursquare); -* Allowed to specify the GrantType after an instance of a client; -* Opened access (public modifier) to basic properties of the OAuth protocol; * Added OAuth client for Assembla; -* Deleted file of the obsolete Helper class (obsolete since v1.4; use OAuthUtility). -##### Thanks: +### Changed +* Allowed to specify the `GrantType` after an instance of a client; +* Opened access (public modifier) to basic properties of the OAuth protocol; + +### Removed +* Deleted file of the obsolete `Helper` class (obsolete since v1.4; use `OAuthUtility`). +### Fixed +* Fixed bug with `DefaultScope` and `Scope`; + +### Thanks * [Nacer](https://github.com/Nacer-) * [codexboise](https://github.com/codexboise) -#### v1.7 (February 11, 2015) +## [v1.7] - 2015-02-11 The version improved for Windows Forms projects. +### Added * Added a data binding for API responses; -* Added ability to specify grant_type: authorization_code (default), password and client_credentials; +* Added ability to specify `grant_type`: `authorization_code` (default), `password` and `client_credentials`; * Added OAuth clients for: CodeProject and SourceForge. -#### v1.6 (January 04, 2015) +## [v1.6] - 2015-01-04 The version includes minor improvements. -* Added OAuthManager.GetClientTypeByName method to obtain the type of client; +### Added +* Added `OAuthManager.GetClientTypeByName` method to obtain the type of client; * Added default scope. -#### v1.5 (December 27, 2014) +## [v1.5] - 2014-12-27 In this version were made significant changes and improvements, which are mainly aimed at simplifying integration with a variety of API. -* Improved transmission parameters in the web request, added support for file transfer; -* Added support for requests: PUT and DELETE; +### Added +* Added support for requests: `PUT` and `DELETE`; * Added methods to perform asynchronous requests; -* Simplified mechanism for generating and usage of the authorization header; * Added support for Unicode to URL encoding method (RFC-3986); -* Unified mechanism for handling responses in various data formats (XML, JSON, PLAIN). Created universal type - UniValue. -* Added OAuth clients for: Instagram and Tumblr. +* Added OAuth clients for: Instagram and Tumblr; +* Unified mechanism for handling responses in various data formats (XML, JSON, PLAIN). Created universal type - `UniValue`. -#### v1.4 (November 2, 2014) +### Changed +* Improved transmission parameters in the web request, added support for file transfer; +* Simplified mechanism for generating and usage of the authorization header. -* Fixed SSL3 problem, completely; -* Fixed problems with Content-Type; -* Fixed minor bugs in OAuthClient (for OAuth 1.0); -* Username-getting for Yandex; -* The Helpers class marked as [Obsolete]. Created new class - OAuthUtility; -* Methods for signature moved to the OAuthUtility class; -* Improved class OAuthAuthorization, added SetSignature method; +## [v1.4] - 2014-11-02 + +### Added * Added the ability to register the clients class by provider name; * Added OAuth clients for: Dropbox, Foursquare, LinkedIn, SoundCloud and Yahoo! -#### v1.3 (October 23, 2014) +### Changed +* The `Helpers` class marked as `[Obsolete]`. Created new class - `OAuthUtility`; +* Methods for signature moved to the `OAuthUtility` class; +* Improved class `OAuthAuthorization`, added SetSignature method; + +### Fixed +* Fixed SSL3 problem, completely; +* Fixed problems with `Content-Type`; +* Fixed minor bugs in `OAuthClient` (for OAuth 1.0); +* Username-getting for Yandex; + +## [v1.3] - 2014-10-23 +### Fixed * Fixed SSL3 problem. -#### v1.2 (October 8, 2014) +## [v1.2] - 2014-10-08 +### Changed * Updated protocol for Odnoklassniki.ru * Improved client for VKontakte: added the ability to receive an email address. - -##### Thanks: +### Thanks * [Aleksander (KamAz) Kryatov](http://vk.com/acid_rock) - -#### v1.1 (July 20, 2014) + +## [v1.1] - 2014-07-20 * First version released. \ No newline at end of file diff --git a/README.md b/README.md index 9813210..6db5986 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -### Nemiro.OAuth +# Nemiro.OAuth **Nemiro.OAuth** is a class library for authorization via **OAuth** protocol in **.NET Framework**. @@ -10,11 +10,11 @@ To install **Nemiro.OAuth**, run the following command in the **Package Manager `PM> Install-Package Nemiro.OAuth` -#### Demo +## Demo http://demo-oauth.nemiro.net/ -### Features +## Features * Support OAuth 1.0 and 2.0; * Obtaining basic information about users: ID, name, sex, date of birth, email address and telephone number; @@ -25,12 +25,12 @@ http://demo-oauth.nemiro.net/ Less code, more functionality! -### System Requirements +## System Requirements -* Microsoft Windows XP, 7 or later with .NET Framework 3.5, 4.0 or 4.5 -* Microsoft Visual Studio 2010 (recommended Professional Edition with Service Pack 1) or later. +* Microsoft Windows XP, 7 or later with .NET Framework 3.5, 4.0, 4.5 or 4.6 +* Microsoft Visual Studio 2013 (recommended Professional Edition with Service Pack 1) or later. -### How to use +## How to use 1\. Create an application at the **OAuth** provider site. @@ -42,9 +42,9 @@ For example, **Facebook**: ```C# OAuthManager.RegisterClient ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" + "facebook", + "1435890426686808", + "c6057dfae399beee9e8dc46a4182e8fd" ); ``` @@ -52,9 +52,9 @@ OAuthManager.RegisterClient ```VBNet OAuthManager.RegisterClient _ ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" + "facebook", + "1435890426686808", + "c6057dfae399beee9e8dc46a4182e8fd" ) ``` @@ -66,22 +66,22 @@ For example: ```C# public partial class ExternalLoginResult : System.Web.UI.Page { - protected void Page_Load(object sender, EventArgs e) - { - var result = OAuthWeb.VerifyAuthorization(); - Response.Write(String.Format("Provider: {0}
", result.ProviderName)); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}
", user.UserId)); - Response.Write(String.Format("Name: {0}
", user.DisplayName)); - Response.Write(String.Format("Email: {0}", user.Email)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - } + protected void Page_Load(object sender, EventArgs e) + { + var result = OAuthWeb.VerifyAuthorization(); + Response.Write(String.Format("Provider: {0}
", result.ProviderName)); + if (result.IsSuccessfully) + { + var user = result.UserInfo; + Response.Write(String.Format("User ID: {0}
", user.UserId)); + Response.Write(String.Format("Name: {0}
", user.DisplayName)); + Response.Write(String.Format("Email: {0}", user.Email)); + } + else + { + Response.Write(result.ErrorInfo.Message); + } + } } ``` @@ -125,6 +125,6 @@ OAuthWeb.RedirectToAuthorization("facebook", returnUrl) ### See Also * [Guide Nemiro.OAuth](http://oauth.nemiro.net) -* [Web Demo](http://demo-oauth.nemiro.net/) -* [Nemiro.OAuth.LoginForms](https://github.com/alekseynemiro/Nemiro.OAuth.LoginForms) +* [Online Demo](http://demo-oauth.nemiro.net/) +* [Forms for Windows Applications](https://github.com/alekseynemiro/Nemiro.OAuth.LoginForms) * [Other projects](http://nemiro.net) diff --git a/README.ru.md b/README.ru.md new file mode 100644 index 0000000..f6459c4 --- /dev/null +++ b/README.ru.md @@ -0,0 +1,135 @@ +# Nemiro.OAuth + +**Nemiro.OAuth** – это библиотека классов для реализации авторизации клиентов по протоколу **OAuth** в проектах **.NET Framework**. + +Библиотека предоставляет полностью готовые клиенты **OAuth** для популярных веб-сайтов с реализованными базовыми функциями получения информации о пользователях. + +Библиотека в первую очередь создавалась для использования в веб-проектах (**ASP.NET MVC**, **WebForms**), но она также может быть использована в консольных приложениях, проектах **Windows Forms** и, теоретически, в других типах проектов. + +Исходный код **Nemiro.OAuth** поставляется на условиях лицензии **Apache License Version 2.0**. + +Для установки **Nemiro.OAuth** выполните следующую команду в консоли диспетчера пакетов (**Package Manager Console**): + +`PM> Install-Package Nemiro.OAuth` + +## Демонстрация + +Посмотреть на работу библиотеки **Nemiro.OAuth** можно на демонстрационном сайте: + +http://demo-oauth.nemiro.net/ + +## Особенности + +* Поддержка протоколов **OAuth 1.0** и **2.0**; +* Получение базовой информации о пользователях (при наличии): ID, полное имя, пол, дата рождения, email и номер телефона; +* **OAuth**-клиенты «из коробки» для: **Amazon**, **Assembla**, **CodeProject**, **Dropbox**, **Facebook**, **Foursquare**, **GitHub**, **Google**, **Instagram**, **LinkedIn**, **Microsoft Live**, **Mail.Ru**, **Odnoklassniki**, **SoundCloud**, **SourceForge**, **Tumblr**, **Twitter**, **VK**, **Yahoo!**, **Yandex**; +* Базовые классы для создания собственных клиентов; +* Унифицированные методы работы с разнообразными **API**. + +Меньше кода, больше возможностей! + +### Требования + +* Microsoft Windows XP, 7 или новее с .NET Framework 3.5, 4.0, 4.5 или 4.6 +* Microsoft Visual Studio 2013 (редакция Professional Edition с Service Pack 1 или выше) или новее. + +### Использование + +1\. На сайте поставщика **OAuth** зарегистрируйте своё приложение. + +2\. Поставщик выдаст идентификатор и секретный ключ вашего приложения. +Используйте их при регистрации поставщика в своём проекте. +В веб-проектах это лучше всего делать в файле `Global.asax` в обработчике события `Application_Start`. + +Например, **Facebook**: + +**C#** +```C# +OAuthManager.RegisterClient +( + "facebook", + "1435890426686808", + "c6057dfae399beee9e8dc46a4182e8fd" +); +``` + +**Visual Basic .NET** +```VBNet +OAuthManager.RegisterClient _ +( + "facebook", + "1435890426686808", + "c6057dfae399beee9e8dc46a4182e8fd" +) +``` + +3\. Создайте страницу обратного вызова и добавьте код получения информации из профиля пользователя с сайта поставщика. + +Например: + +**C#** +```C# +public partial class ExternalLoginResult : System.Web.UI.Page +{ + protected void Page_Load(object sender, EventArgs e) + { + var result = OAuthWeb.VerifyAuthorization(); + Response.Write(String.Format("Поставщик: {0}
", result.ProviderName)); + if (result.IsSuccessfully) + { + var user = result.UserInfo; + Response.Write(String.Format("Идентификатор: {0}
", user.UserId)); + Response.Write(String.Format("Отображаемое имя: {0}
", user.DisplayName)); + Response.Write(String.Format("Электронная почта: {0}", user.Email)); + } + else + { + Response.Write(result.ErrorInfo.Message); + } + } +} +``` + +**Visual Basic .NET** +```VBNet +Public Class ExternalLoginResult + Inherits System.Web.UI.Page + + Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load + Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() + Response.Write(String.Format("Provider: {0}
", result.ProviderName)) + If result.IsSuccessfully Then + Dim user As UserInfo = result.UserInfo + Response.Write(String.Format("Идентификатор: {0}
", user.UserId)) + Response.Write(String.Format("Отображаемое имя: {0}
", user.DisplayName)) + Response.Write(String.Format("Электронная почта: {0}", user.Email)) + Else + Response.Write(result.ErrorInfo.ToString()) + End If + End Sub + +End Class +``` + +4\. Создайте ссылку для перенаправления пользователя на сайт поставщика **OAuth** для авторизации. + +**C#** +```C# +string returnUrl = new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri; +OAuthWeb.RedirectToAuthorization("facebook", returnUrl); +``` + +**Visual Basic .NET** +```VBNet +Dim returnUrl As String = New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri +OAuthWeb.RedirectToAuthorization("facebook", returnUrl) +``` + +5\. Наслаждайтесь! + +### См. также + +* [Справочник](http://oauth.nemiro.net) +* [Online-демонстрация](http://demo-oauth.nemiro.net/) +* [Готовые формы для Windows Forms](https://github.com/alekseynemiro/Nemiro.OAuth.LoginForms) +* [Другие проекты](http://nemiro.net) diff --git a/bin/ReadMe.md b/bin/ReadMe.md deleted file mode 100644 index 60a74c0..0000000 --- a/bin/ReadMe.md +++ /dev/null @@ -1,6 +0,0 @@ -Select the assembly for your .NET Framework version: -* net35 - .NET Framework 3.5 -* net40 - .NET Framework 4.0 -* net45 - .NET Framework 4.5 - -Main platform is .NET Framework 4.0 \ No newline at end of file diff --git a/bin/net35/Nemiro.OAuth.XML b/bin/net35/Nemiro.OAuth.XML deleted file mode 100644 index a3747bd..0000000 --- a/bin/net35/Nemiro.OAuth.XML +++ /dev/null @@ -1,9540 +0,0 @@ - - - - Nemiro.OAuth - - - - - The universal type that represents a value. - - - represents any type of data. - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the with a specified value. - - The value. - - - - Initializes a new instance of the with a specified value and attributes. - - The value. - The collection of an attributes. - - - - Initializes a new instance of the with a specified value and reference to parent. - - The value. - The instance of the . - - - - Initializes a new instance of the with a specified value, attributes and reference to parent. - - The value. - The collection of an attributes. - The instance of the . - - - - Copies items of the to a new Dictionary<string, object>. - - - A Dictionary<string, object> containing copies of the elements of the . - A null value, if the property is false or the is empty. - - - - - Copies items of the to a new . - - - A containing copies of the elements of the . - A null value, if the property is false or the is empty. - - - - - Returns a array that represents the current . - - - A array containing the current . - A null value, if the property and is false or the is empty. - - - - - Determines whether the contains the specified key. - - The key to locate in the . - true if the is not null and contains an element with the specified ; otherwise, false. - is null. - - - - Determines whether the contains the specified key. - - The key to locate in the . - true if the is not null and contains an element with the specified ; otherwise, false. - - - - Adds the specified key and value to the . - - The key of the element to add. - The value of the element to add. - - Returns the added element. - - - - If the current is not a collection ( is false), it will automatically be converted to the collection. - If the current is not empty, then it will be assigned a key ____ in a new collection. - - - - - - Adds the specified key and value to the . - - The key of the element to add. - The value of the element to add. - The reference to parent of the elemet to add. - - Returns the added element. - - - - If the current is not a collection ( is false), it will automatically be converted to the collection. - If the current is not empty, then it will be assigned a key ____ in a new collection. - - - - - - Removes the value with the specified key from the . - - The key of the element to remove. - - true if the element is successfully found and removed; otherwise, false. - This method returns false if key is not found in the or is not collection ( is false). - - - - - Parses the and converts to . - - The reference to the collection, which will be placed the result of parsing . - The for parsing. - The reference to parent. - - - - Returns the of the specified attribute. - - The name of the attribute whose value you want to get. - - - - Returns parent for new instance of . - - - - - Initializes a new instance. - - - - - Initializes a new instance with a specified . - - The value. - - - - Initializes a new instance with a specified and . - - The value. - The collection of an attributes. - - - - Initializes a new instance with a specified and reference to . - - The value. - The instance of the . - - - - Initializes a new instance with a specified , and reference to . - - The value. - The instance of the . - The collection of an attributes. - - - - Initializes an empty instance with a specified and reference to . - - The collection of an attributes. - The instance of the . - - - - Converts the specified JSON string to an . - - A string containing a JSON data to parse. - A new instance. - is null. - The length exceeds the value of . - The recursion limit defined by was exceeded. - contains an unexpected character sequence. - is a dictionary type and a non-string key value was encountered. - includes member definitions that are not available on the target type. - It is not possible to convert to the target type. - - - - Converts the specified XML string to an . - - A string containing a XML data to parse. - A new instance. - is null. - - - - Converts the specified parameters string to an . - - A string containing an url parameters to parse. - A new instance. - contains an CR or LF characters. - - If is null or empty, the function returns an instance. - - - - - Converts the specified JSON string to an . A return value indicates whether the conversion succeeded. - - A string containing a JSON data to parse. - If successful, this parameter takes the result of parsing data. - true if s was converted successfully; otherwise, false. - - - - Converts the specified XML string to an . A return value indicates whether the conversion succeeded. - - A string containing a XML data to parse. - If successful, this parameter takes the result of parsing data. - true if s was converted successfully; otherwise, false. - - - - Converts the specified url parameters string to an . A return value indicates whether the conversion succeeded. - - A string containing an url parameters to parse. - If successful, this parameter takes the result of parsing data. - true if s was converted successfully; otherwise, false. - - - - Indicates whether the specified value is null or an . - - The instance to test. - true if the parameter is null or is false; otherwise, false. - - - - Gets the underlying type code of the . - - - - - - Converts the value of this instance to an equivalent value using the specified culture-specific formatting information. - - An object that supplies culture-specific formatting information. - A value equivalent to the value of this instance. - - - - - - Converts the value this instance to an equivalent 8-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 8-bit unsigned integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent Unicode character using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A Unicode character equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A instance equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent number using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A number equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent double-precision floating-point number using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A double-precision floating-point number equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 16-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 16-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 32-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 32-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 64-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 64-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 8-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 8-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent single-precision floating-point number using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A single-precision floating-point number equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A instance equivalent to the value of this instance. - - - - Converts the value of this instance to an of the specified that has an equivalent value, using the specified culture-specific formatting information. - - The to which the value of this instance is converted. - An interface implementation that supplies culture-specific formatting information. - An instance of type whose value is equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 16-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 16-bit unsigned integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 32-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 32-bit unsigned integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 64-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 64-bit unsigned integer equivalent to the value of this instance. - - - - Creates a new object that is a copy of the current instance. - - A new object that is a copy of this instance. - - - - Returns an enumerator that iterates through a collection. - - An object that can be used to iterate through the collection. - - - - Returns an enumerator that iterates through a collection. - - An System.Collections.IEnumerator<UniValue> object that can be used to iterate through the collection. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Serves as a hash function for a particular type. - - A hash code for the current . - - - - Returns a string that represents the current . - - - - - Determines whether two object instances are equal. - - The object to compare with the current instance of the . - true if the specified object is equal to the current ; otherwise, false. - - - - Determines whether two instances are equal. - - The to compare with the current instance of the . - true if the specified is equal to the current ; otherwise, false. - - - - Determines whether this instance and another specified object have the same value. - - The string to compare to this instance of the . - true if the value of the parameter is the same as this instance; otherwise, false. - - - - Determines whether this string and a specified object have the same value. A parameter specifies the culture, case, and sort rules used in the comparison. - - The string to compare to this instance. - One of the enumeration values that specifies how the strings will be compared. - true if the value of the parameter is the same as this instance; otherwise, false. - - - - Converts the as a . - - The instance. - - - - Converts the as a Dictionary<string, object>. - - The instance. - - - - Converts the as an array. - - The instance. - - - - Converts the as an array. - - The instance. - - - - Converts the as a array. - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from Dictionary<string, object>. - - The value from which will be created a new instance of the . - - - - Creates a new instance from array. - - The value from which will be created a new instance of the . - - - - Creates a new instance from array. - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Indicate whether two are not equal. - - The first instance. - The second instance. - - - - Indicate whether two are equal. - - The first instance. - The second instance. - - - - Indicate whether and are not equal. - - The instance. - The string. - - - - Indicate whether and are equal. - - The instance. - The string. - - - - Returns an that can be bound to a data source from an object that does not implement an itself. - - - - - Returns a collection of custom attributes for this instance of a component. - - - - - Returns the class name of this instance of a component. - - - - - Returns the name of this instance of a component. - - - - - Returns a type converter for this instance of a component. - - - - - Returns the default event for this instance of a component. - - - - - Returns the default property for this instance of a component. - - - - - Returns an editor of the specified type for this instance of a component. - - A that represents the editor for this object. - - - - Returns the events for this instance of a component using the specified attribute array as a filter. - - An array of type that is used as a filter. - - - - Returns the events for this instance of a component. - - - - - Returns the properties for this instance of a component using the attribute array as a filter. - - An array of type that is used as a filter. - - - - Returns the properties for this instance of a component. - - - - - Returns an object that contains the property described by the specified property descriptor. - - A that represents the property whose owner is to be found. - - - - Gets or sets the value. - - - - - Gets a collection of string keys and values of the current . - - - Has a null value, if the property is false. - - - - - Gets or sets an attributes of the XML item (only for XML). - - - - - Gets the value associated with the specified key of the . - - The key of the value to get. - - - - Gets the value associated with the specified index of the . - - The index of the value to get. - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to array. - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to numeric type. - - - - - Gets a value indicating whether the current object has a value. - - - - - Gets a value indicating whether the current object has an attributes (only for xml data type). - - - - - Gets the number of elements actually contained in the . - - - - - Gets or sets the key for the current item, if the current item included into the collection. - - - Assigned automatically when parsing data of JSON, XML or query string. - root for root elements. - value for . - ____ for new collections created by the developer manually. - - - - - The parent of the current item, if the current item included into the collection. - - - - - Gets or sets a value that indicates whether the data type of the is array. - - - This affects the representation of the object as a string. For arrays in a JSON is not use the . - - - - - Gets or sets a value that indicates whether the type is unreferenced. - - - - - Represents the empty . - - - - - Gets a value indicating whether the collection is a collection of objects. - - - - - Implements a parameter of url. - - - - - Implements a HTTP paramter. - - - - - Initializes a new instance of the class. - - The name of the parameter. - The value of the parameter. - The content-type of the parameter. - - - - Initializes a new instance of the class. - - The name of the parameter. - The value of the parameter. - The type of the parameter. - The content-type of the parameter. - - - - Returns a string that represents the current parameter. - - - - - Gets or sets parameter name. - - - - - Gets or sets parameter value. - - - - - Gets or sets Content-Type. - - - - - Gets or sets type of the parameter. - - - - - Initializes a new instance of the class with a specified parameter name and value. - - The parameter value. - The parameter name. - - - - Represents a class that extends the class by adding methods for use with query parameters. - - - - - Convert the to list of the . - - The . - - - - Returns a string of query parameters without a separator. - - The . - - - - Returns a string of query parameters with a specified separator. - - The . - The separator of query parameters. For example: & - - - - Returns a string of query parameters with a specified encoding parameters. - - The . - Disables parameters encoding. - - - - Returns a string of query parameters with a specified separator and encoding parameters. - - The . - The separator of query parameters. - Disables parameters encoding. - - - - Sorts the by alphabetically and returns a new . - - The . - - - - Removes the value with the specified key from the . - - The . - The key of the element to remove. - - - - The exception occurs when you try to access a provider by provider name. If the name is incorrect, or does not exist. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with a specified error message. - - The error message that explains the reason for this exception. - An object array that contains zero or more objects to format. - - - - The exception that is thrown when trying to access an unregistered OAuth client. - - - Use the for OAuth clients registration. - - - The following example illustrates a situation in which the is thrown. - - string url = OAuthWeb.GetAuthorizationUrl("facebook"); - // ... - - - Dim url As String = OAuthWeb.GetAuthorizationUrl("facebook"); - ' ... - - ClientIsNotRegisteredException - To solve the problem enough to register the client. - - // facebook client registration - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - ' facebook client registration - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - Enjoy! - - string url = OAuthWeb.GetAuthorizationUrl("facebook"); - // ... - - - Dim url As String = OAuthWeb.GetAuthorizationUrl("facebook"); - ' ... - - - - - - Initializes a new instance of the class. - - - - - OAuth client for Google. - - -

Register and Configure a Google Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Google Developers Console and Create Project. - - Create new project button - - Enter the project name and click the Create. - - Create new project form - - - Click to the Credential menu in the APIs & OAuth. - - - Credential menu - - - For desktop application, click the Create new Client ID, select Installed application and Other. - - - Click the Create Client ID to complete. - - - Create new Client ID for desktop application - - - You will get the Client ID and Client Secret. - Use this for creating an instance of the . - - - Create new Client ID for desktop application - - - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - For web projects create another Client ID. In the form select the Web application and specify return addresses. - - Create new Client ID for web application - - - For more details, please visit Google Developers Console Help. - -
- - The following example shows how to use the in Console Applications. - For desktop applications, the user will need to manually enter authorization code. - - class Program - { - static void Main(string[] args) - { - try - { - var google = new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - // open the login page in browser - System.Diagnostics.Process.Start(google.AuthorizationUrl); - - // waiting of entering the access code - string code = ""; - while (String.IsNullOrEmpty(code)) - { - Console.WriteLine("Enter access code:"); - code = Console.ReadLine(); - } - - Console.WriteLine(); - - // set authorization code - google.AuthorizationCode = code; - // get user info - var user = google.GetUserInfo(); - Console.WriteLine("User ID: {0}", user.UserId); - Console.WriteLine("Name: {0}", user.DisplayName); - Console.WriteLine("Email: {0}", user.Email); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - Console.ReadKey(); - } - } - - - Module Module1 - - Sub Main() - Try - Dim google As New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ' open the login page in browser - System.Diagnostics.Process.Start(google.AuthorizationUrl) - - ' waiting of entering the access code - Dim code As String = "" - Do While String.IsNullOrEmpty(code) - Console.WriteLine("Enter access code:") - code = Console.ReadLine() - Loop - - ' set authorization code - google.AuthorizationCode = code - - ' get user info - Dim user As UserInfo = google.GetUserInfo() - Console.WriteLine("User ID: {0}", user.UserId) - Console.WriteLine("Name: {0}", user.DisplayName) - Console.WriteLine("Email: {0}", user.Email) - Catch ex As Exception - Console.WriteLine(ex.Message) - End Try - Console.ReadKey() - End Sub - - End Module - - Result of the program is shown in the images below. - Log in with Google - Access code - User info - In a web projects you can use the and . - The following example shows how use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-fscjqht7ou30a75gjkde1eu1brsvbqkn.apps.googleusercontent.com", - "SI5bIZkrSB5rO03YF-CdsCJC" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-fscjqht7ou30a75gjkde1eu1brsvbqkn.apps.googleusercontent.com", - "SI5bIZkrSB5rO03YF-CdsCJC" - ) - ) - End Sub - - The GoogleLoginResult method will handle authorization result. - - public ActionResult GoogleLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function GoogleLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Google. - - public ActionResult GoogleLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Google", Url.Action("GoogleLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function GoogleLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Google", Url.Action("GoogleLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the GoogleLogin method. - - @Html.ActionLink("Log in with Google", "GoogleLogin") - - - - - - - - - - - - - - - - - - - - - - -
- - - Represents base properties and method for OAuth 2.0 client. - - - For more details, please visit . - - - - - Represents base class for OAuth client classes. - - - - - Initializes a new instance of the class. - - The address for login. - The address for the access token. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - - is null or empty. - -or- - is null or empty. - -or- - is null or empty. - -or- - is null or empty. - - - - - Redirects a client to the Authorization URL. - - - Use this method only for web applications (ASP .NET). - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Gets the access token from the remote server. - - - This is method is implemented at the protocol level ( & ). - - The is null or empty. - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Gets the user details via API of the provider. - - May contain an access token, which will have to be used in obtaining information about the user. - - This is method is implemented at the client level. - - - - - Creates a shallow copy of the current object. - - The query parameters for new copy object. - The new return URL for new copy object. - A shallow copy of the current object. - - Method creates a copy of the current object, removes tokens, change the return address, query parameters and state. - Unfortunately, I made a mistake in architecture, so I had to make this method. - - - - - - Creates a shallow copy of the current object. - - A shallow copy of the current object. - - Method creates a copy of the current object, removes tokens, change the return address, query parameters and state. - Unfortunately, I made a mistake in architecture, so I had to make this method. - - - - - - Returns the specified access token or the current access token. - - May contain an access token, which will be refunded. - Indicates the need to check the parameter refresh_token in the access token. Default: false. - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - - - - Unique provider name. - - - Client classes are required to implement this property. - The provider name must be unique. - - - - public override string ProviderName - { - get - { - return "KGB"; - } - } - - - - - - Gets the endpoint of the authorization. - - - This property is implemented at the protocol level ( & ). - - - - - Gets or sets an access token. - - - - - Gets an access token value. - - - - - Gets or sets access code for access token requests. - - - - - Gets or sets unique request identifier. - For clients the value sets is automatically. - - - - - Gets or sets the application identifier. - - - - - Gets or sets the application secret key. - - - - - Gets or sets the base address for login. - - - - - Gets or sets the address for the access token. - - - - - Gets the version of the OAuth protocol. - - - - - Gets or sets return URL. - - - At this address provider will return the user authorization results. - For many providers are needed configuration of the application on the provider website. - - - - - Gets or sets additional query parameters. - - - These parameters will be transferred to the provider. - - - - - Gets or sets a value indicating whether the current client supports revoking access token. - - - - - Gets or sets a value indicating whether the current client supports refreshing access token. - - - - - Initializes a new instance of the class. - - The address for login. - The address for the access token. - The application identifier. - The application secret key. - - - - Gets the access token from the remote server. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - The scope of the access request. - - - - - The deault scope. - - - - - The separator in the scope list. - - - - - Gets or sets grant type. - - - - - Gets or sets username if is password or client_credentials. - - - - - Gets or sets password if is password or client_credentials. - - - - - Gets the endpoint of the authorization. - - - - - Initializes a new instance of the . - - The Client ID obtained from the Google Developers Console. - The Client Secret obtained from the Google Developers Console. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - In order to Google returned the refresh_token, when receiving an access token, you must specify access_type=offline. - - - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - { - Parameters = new NameValueCollection { { "access_type", "offline" } } - } - ); - - - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) With _ - { - .Parameters = New NameValueCollection() From {{"access_type", "offline"}} - } - ) - - For more details, please see Google Documentation. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Google. - - - - - Return URL. - - - - - Represents the empty results of the query. - - - The class is used to determine sends a request to the remote server or not. - - - - - Represents the base class for results of remote requests. - - - - - Initializes a new instance of the class. - - The request results. - - - - Initializes a new instance of the class. - - The content type of the response. - The source of the response. - - - - Initializes a new instance of the class. - - The content type of the response. - The source of the response. - The HTTP headers of the response. - The HTTP status code of the response. - - - - Parses the source to the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets or sets the HTTP status code of the output returned to the client. - - - - - Gets a value indicating whether the current request result is successful or not. - - - Successful result - is a response code from 200 to 299. - - - - - Gets or sets the content type of the response. - - - - - Gets or sets the http headers of the response. - - - - - Gets the Content-Disposition header of the response. - - - - - Gets the file name, if is file. - - - - - Gets or sets the source of the response. - - - - - Gets a value indicating the is file or not. - - - - - Gets a value indicating whether the is empty or not. - - - - - Gets or sets the processed result of the response. - - - - - Gets a value indicating the is or not. - - - - - Gets a value indicating the is or not. - - - - - Gets a value indicating the is XML or not. - - - - - Gets a value indicating the is array or not. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets a value indicating whether the current request result is successful or not. - - Always has the value false. - - - - Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. - - - - - Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. - - - - - Перезаписывает свойство CurrentUICulture текущего потока для всех - обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. - - - - - Поиск локализованного ресурса типа System.Drawing.Bitmap. - - - - - Ищет локализованную строку, похожую на Aleksey Sergeevich Nemiro is a Russian developer of applications and websites, - author of articles on programming and information technology. - - Aleksey was born on October 3, 1983 in the city of Vladivostok (Primorsky Krai, Russia). - In 2009, Aleksey migrated to the city of Yoshkar-Ola (Mari El, Russia). - - Started programming in 1998 on the G-Basic and QBasic. - - At various times worked with programming languages and technologies: - Visaul Basic, Delphi, C, Visual C++, Java, PHP, ASP VBScript and JScript [остаток строки не уместился]";. - - - - - The access token class for OAuth 1.0. - - - - - Represents base properties and method for access token results. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - Result of request to the OAuth server. - - - - Returns the . - - - - - Converts the specified string to an . - - A string containing an access token to parse. - A new instance. - - - - Converts the specified string to an . - - Type Inherited from the that should be returned. - A string containing an access token to parse. - A new instance. - - - - Indicates whether the specified value is null or an . - - The instance to test. - true if the parameter is null or is false; otherwise, false. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - The access token issued by the authorization server. - - - - - Represents the empty . - - - - - Gets a value indicating whether the is empty or not. - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Initializes a new instance of the class. - - Result of request to the OAuth server. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Returns the . - - - - - Converts the specified string to an . - - A string containing an access token to parse. - A new instance. - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - The access token issued by the authorization server. - - - - - The access token issued by the authorization server. - - - - - The access token class for OAuth 2.0. - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Initializes a new instance of the class. - - Result of request to the OAuth server. - - - - Initializes a new instance of the class with a specified access token and refresh token. - - The access token. - The refresh token. - - - - Initializes a new instance of the class with a specified access token and refresh token. - - The access token. - The refresh token. - The token type. For example: bearer. Default: null. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Returns the . - - - - - Converts the specified string to an . - - A string containing an access token to parse. - A new instance. - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - The access token issued by the authorization server. - - - - - The lifetime in seconds of the access token. - - - - - The refresh token, which can be used to obtain new - access tokens using the same authorization grant. - - - - - The scope of the access token. - - - - - The type of the token issued. Value is case insensitive. - - - - - The exception that is thrown when server of API returns error. - - - - - The exception that is thrown when an error occurs while accessing the network. - - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The content type of the server request result. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The content type of the server request result. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - The HTTP headers of the output. - The HTTP status code of the output. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Instance of the . - - - - - Gets the HTTP status code of the output returned to the client. - - - - - Gets the content type of the response. - - - - - Gets the http headers of the response. - - - - - Initializes a new instance of the class with a specified and the exception that is the cause of this exception. - - The result of the request. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class with a specified and error message. - - The result of the request. - The error message that explains the reason for this exception. - - - - Initializes a new instance of the class with a specified error message. - - The error message that explains the reason for this exception. - - - - Initializes a new instance of the class with a specified error message and the exception that is the cause of this exception. - - The error message that explains the reason for this exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - The content type of the server request result. - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - The content type of the server request result. - - - - Initializes a new instance of the class with a specified server request result, content type and a error message. - - The result of the request. - The error message that explains the reason for this exception. - The content type of the server request result. - - - - Initializes a new instance of the class with a specified server request result, content type and a error message. - - The result of the request. - The error message that explains the reason for this exception. - The content type of the server request result. - - - - OAuth client for Twitter. - - -

Register and Configure a Twitter Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Consumer ID and Consumer Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Twitter Application Management and Create a New App. - - Create a New App button - - Fill out the form and click the Create your Twitter application. - For web project, set a Callback URL. - - Create a New App form - - - Open the application page and click to the API Keys. - - - API Keys link - - - You can see API Key and API secret, this is Consumer Key and Consumer Secret. - Use this for creating an instance of the . - - - Client ID and Client Secret - - - OAuthManager.RegisterClient - ( - new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - - - For more details, please visit Twitter Developers Documentation. - -
- -

Console Applications

- The following example shows how to use the in Console Applications. - For desktop applications, the user will need to manually enter authorization code. - - class Program - { - static void Main(string[] args) - { - try - { - var twitter = new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ); - - // open the login page in browser - System.Diagnostics.Process.Start(twitter.AuthorizationUrl); - - // waiting of entering the access code - string code = ""; - while (String.IsNullOrEmpty(code)) - { - Console.WriteLine("Enter access code:"); - code = Console.ReadLine(); - } - - Console.WriteLine(); - - // set authorization code - twitter.AuthorizationCode = code; - // get user info - var user = twitter.GetUserInfo(); - Console.WriteLine("User ID: {0}", user.UserId); - Console.WriteLine("Name: {0}", user.DisplayName); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - Console.ReadKey(); - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Module Module1 - - Sub Main() - Try - Dim twitter As New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ' open the login page in browser - System.Diagnostics.Process.Start(twitter.AuthorizationUrl) - - ' waiting of entering the access code - Dim code As String = "" - Do While String.IsNullOrEmpty(code) - Console.WriteLine("Enter access code:") - code = Console.ReadLine() - Loop - - ' set authorization code - twitter.AuthorizationCode = code - - ' get user info - Dim user As UserInfo = twitter.GetUserInfo() - Console.WriteLine("User ID: {0}", user.UserId) - Console.WriteLine("Name: {0}", user.DisplayName) - Catch ex As Exception - Console.WriteLine(ex.Message) - End Try - Console.ReadKey() - End Sub - - End Module - - Result of the program is shown in the images below. - Log in with Twitter - Access code - User info -

ASP .NET WebForms

- In a web projects you can use the and . - The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkTwitter" runat="server" - Text="Log in with Twitter" onclick="lnkTwitter_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkTwitter_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Twitter", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkTwitter_Click(sender As Object, e As EventArgs) Handles lnkTwitter.Click - OAuthWeb.RedirectToAuthorization("Twitter", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - - NOTE: Do not forget to adjust the Callback URL in the Twitter Application Settings. -
- - - - - - - - - - - - - - - - - - - - -
- - - Represents base properties and method for OAuth 1.0 client. - - - For more details, please visit . - - - - - Initializes a new instance of the class. - - The address for the request token. - The address for login. - The address for the access token. - The application identifier. - The application secret key. - The name of hashing algorithm to calculate the signature: HMAC-SHA1 (default) or PLAINTEXT. - The is null or empty. - - - - Gets base string of the signature for current request. - - For more details, please visit - - - - Gets signature for the current request. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - - - - Gets the request token from the remote server. - - - - - Gets the access token from the remote server. - - - - - Gets or sets the address for the request token. - - - - - Get the authorization parameters. - - - - - Gets the endpoint of the authorization. - - - - - Gets or sets the request token. - - - - - Initializes a new instance of the . - - The API Key obtained from the Twitter Application Management. - The API Secret obtained from the Twitter Application Management. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Unique provider name: Twitter. - - - - - OAuth client for LinkedIn. - - -

Register and Configure a LinkedIn Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open and sigin to the LinkedIn for Developers, and Add new app. - - In the application settings you can found Api Key and Secret Key. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new LinkedInClient - ( - "75vufylz829iim", - "VOf14z4T1jie4ezS" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New LinkedInClient _ - ( - "75vufylz829iim", - "VOf14z4T1jie4ezS" - ) - ) - - - For more details, please visit LinkedIn for Developers. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Api Key obtained from the LinkedIn Dashboard. - The Secret Key obtained from the LinkedIn Dashboard. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: LinkedIn. - - - - - OAuth client for SoundCloud. - - -

Register and Configure a SoundCloud Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the SoundCloud for Developers and Register a new app. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new SoundCloudClient - ( - "42b58d31e399664a3fb8503bfcaaa9ba", - "f9d85648da59fb95ec131b40c7645c31" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New SoundCloudClient _ - ( - "42b58d31e399664a3fb8503bfcaaa9ba", - "f9d85648da59fb95ec131b40c7645c31" - ) - ) - - - For more details, please visit SoundCloud for Developers. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the SoundCloud Applications. - The Client Secret obtained from the SoundCloud Applications. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: SoundCloud. - - - - - Implements a form parameter. - - - - - Initializes a new instance of the class with a specified parameter name and value. - - The parameter value. - The parameter name. - - - - Represents data mapping collection for API results. - - - - - Initializes a new instance of the class. - - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - The data type. - The data format. For example: "dd.MM.yyyy" for dates, or: "00" for numerics, etc. - Custom parser of the data. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - The data type. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - The data type. - The data format. For example: "dd.MM.yyyy" for dates, or: "00" for numerics, etc. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - Custom parser of the data. - - - - The list of url encding methods. - - - - - Without encoding. - - - - - for POST requests when a conetent-type is x-www-form-urlencoded. - And for other requests. - - - - - x-www-form-urlencoded (spaces encoded as plus (+) signs). - - - - - RFC 3986 (spaces encoded as %20). - - - - - OAuth client for CodeProject. - - -

Register and Configure a CodeProject Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - - Register a new client. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new CodeProjectClient - ( - "92mWWELc2DjcL-6tu7L1Py6yllleqSCt", - "YJXrk_Vzz4Ps02GqmaUY-aSLucxh4kfLq6oq0CtiukPfvbzb9yQG69NeDr2yiV9M" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New CodeProjectClient _ - ( - "92mWWELc2DjcL-6tu7L1Py6yllleqSCt", - "YJXrk_Vzz4Ps02GqmaUY-aSLucxh4kfLq6oq0CtiukPfvbzb9yQG69NeDr2yiV9M" - ) - ) - - - For more details, please see CodeProject API Documentation. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the CodeProject Web API Clients. - The Client Secret obtained from the CodeProject Web API Clients. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: CodeProject. - - - - - OAuth client for Microsoft Live. - - -

Register and Configure a Live Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Live Connect App Management and Create a New Application. - - Create a New Application - - Specify the application name, read terms of use and click the I accept. - - Create a New Application form - - Open the App Settings and add return URLs. You can't use localhost. - - Redirect URLs - - On the App Settings page, you can found Client ID and Client Secret. - - Use this for creating an instance of the . - - - Cleint ID and Client Secret - - - OAuthManager.RegisterClient - ( - new LiveClient - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New LiveClient _ - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ) - - - For more details, please visit to the MSDN. - -
- - The following example shows how to add the Microsoft Live OAuth Client to ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new LiveClient - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New LiveClient _ - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ) - End Sub - - The LiveLoginResult method will handle authorization result. - - public ActionResult LiveLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function LiveLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Microsoft Live. - - public ActionResult LiveLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Live", Url.Action("LiveLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function LiveLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Live", Url.Action("LiveLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the LiveLogin method. - - @Html.ActionLink("Log in with Microsoft Live", "LiveLogin") - - Result shown in the images below. - Microsoft Live Sign in - User Info - - - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the Live Connect App Management. - The Client Secret obtained from the Live Connect App Management. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - In order to Microsoft Live returned the refresh_token, when receiving an access token, you must specify the scope wl.offline_access. - - - OAuthManager.RegisterClient - ( - new LiveClient - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - { - Scope = "wl.offline_access" - } - ); - - - OAuthManager.RegisterClient _ - ( - New LiveClient _ - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) With { .Scope = "wl.offline_access" } - ) - - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Live. - - - - - The exception that is thrown when HttpContext.Current is null (Nothing in Visual Basic). - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Initializes a new instance of the class. - - - - - The exception that is thrown when you attempt to register the already registered client. - - - - - Initializes a new instance of the class. - - The name of the provider. - - - - Initializes a new instance of the class. - - The name of the provider and client. - - - - Gets an error message. - - - - - OAuth client for Amazon. - - -

Register and Configure Amazon Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - You need to register as developer in the App Console. - - - Sign in to the App Console - - - In the App Console register new application. - - - Register new application - - - Specify one or more return URLs. Access to any other address will be denied. - - - NOTE: Amazon supports only addresses over HTTPS (excluding localhost). - - - For example: - - https://hamster.example.org/Home/ExternalLoginResult - http://localhost:59962/Home/ExternalLoginResult - http://localhost/ - - - - Allowed Return URLs - - Do not forget to save your changes. - Use application Client ID and Client Secret when creating an instance of the class. - - Allowed Return URLs - - - OAuthManager.RegisterClient - ( - new AmazonClient - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New AmazonClient _ - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ) - - - For more details, please see Amazon Developer Documentation. - -
- - The following example shows how to add the Amazon OAuth Client to ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new AmazonClient - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New AmazonClient _ - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ) - End Sub - - The ExternalLoginResult method will handle authorization result. - - public ActionResult ExternalLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function ExternalLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Now you can easily redirect user to login page. - - // NOTE: use httpS scheme for real websites - string authUrl = OAuthWeb.GetAuthorizationUrl("Amazon", Url.Action("ExternalLoginResult", "Home", null, null, Request.Url.Host)); - // for example, MVC redirection from Action: - // return Redirect(authUrl); - - - ' NOTE: use httpS scheme for real websites - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Amazon", Url.Action("ExternalLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - ' for example, MVC redirection from Action - ' Return Redirect(authUrl) - - Result shown in the images below. - Amazon Sign in - Amazon User Info - - - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the class. - - The client ID obtained from the App Console. - The client secret obtained from the App Console. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Amazon. - - - - - Additional type for references. - - - - - Represents the signature of the request. This is a helper class to simplify debugging. - - - - - Initializes a new instance of the class. - - The name of hashing algorithm to calculate the signature: HMAC-SHA1 (default) or PLAINTEXT. - The secret key for encryption. - Base string of the signature. - - is not suppored. - - - - - Returns the of the current object. - - - - - Gets the secret key for encryption. - - - - - Gets the name of hashing algorithm to calculate the signature: HMAC-SHA1 or PLAINTEXT. - - - - - Get base string of the signature. - - - - - Gets the signature. - - - - - Implements a value of the HTTP paramter. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Returns an encoded string of the value. - - - - - Returns an encoded string of the value. - - - - - Returns a string that represents the current value. - - - - - Returns a byte array that represents the current value. - - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the array of the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Gets or sets value. - - - - - OAuth client for Dropbox. - - -

Register and Configure a Dropbox Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Dropbox App Console and Create app. - Choose the Dropbox API app type. - - In the application settings you can found App key and App secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new DropboxClient - ( - "0le6wsyp3y085wy", - "48afwq9yth83y7u" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New DropboxClient _ - ( - "0le6wsyp3y085wy", - "48afwq9yth83y7u" - ) - ) - - - For more details, please visit Dropbox Platform Help. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The App key obtained from the Dropbox App Console. - The App secret obtained from the Dropbox App Console. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Unique provider name: Dropbox. - - - - - Variants of the signature encryption. - - - - - HMAC-SHA1 - - - - - RSA-SHA1 - - - - - PLAINTEXT - - - - - Represents helper class for management of OAuth clients. - - - You can use this class to register clients in your project. - - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Initializes the . - - - - - The method is called when the interval elapsed. - - Instance of the object that raised the event. - The event data. - - - - Adds the specified request to the collection. - - The unique request key. - The client name. - The client instance. - - - - Removes the request from collection. - - The unique request key to remove.. - - - - Registers the specified client in the application. - - The client instance. - is null or empty. - If you attempt to register the already registered client. - - - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Registers the specified client in the application. - - The client instance. - The any name of the client. For example: Test, Release, Project #1, Ku!, Example.org etc. - is null or empty. - If you attempt to register the already registered client. - - - OAuthManager.RegisterClient - ( - "Test", - new GoogleClient - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Test", - new FacebookClient - ( - "00000000000000", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - "Test", - New GoogleClient _ - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Test", - New FacebookClient _ - ( - "00000000000000", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Registers the specified client in the application. (the main method) - - The client instance. - The any name of the client. For example: Test, Release, Project #1, Ku!, Example.org etc. - is null or empty. - If you attempt to register the already registered client. - - - OAuthManager.RegisterClient - ( - "Test", - new GoogleClient - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Test", - new FacebookClient - ( - "00000000000000", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - "Test", - New GoogleClient _ - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Test", - New FacebookClient _ - ( - "00000000000000", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Registers the specified client in the application. - - The provider name. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - , or is null or empty. - Provider not found by . - - - OAuthManager.RegisterClient - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - OAuthManager.RegisterClient - ( - "facebook" - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ); - - - OAuthManager.RegisterClient _ - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - - OAuthManager.RegisterClient _ - ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - - - - - - Registers the specified client in the application. - - The provider name. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - List of scope that will be requested from the provider. Only for OAuth 2.0. - Additional parameters to be passed to the constructor of the client class. - Additional parameters that will be transferred to the provider website. - , or is null or empty. - Provider not found by . - The not suppored . - - - OAuthManager.RegisterClient - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - OAuthManager.RegisterClient - ( - "facebook" - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ); - - - OAuthManager.RegisterClient _ - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - - OAuthManager.RegisterClient _ - ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - - - - - - Registers the specified client in the application. - - The provider name. And may also contain any client name for for division into groups. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - Additional parameters to be passed to the constructor of the client class. - List of scope that will be requested from the provider. Only for OAuth 2.0. - Additional parameters that will be transferred to the provider website. - , or is null or empty. - Provider not found by . - The not suppored . - - - OAuthManager.RegisterClient - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - OAuthManager.RegisterClient - ( - "facebook" - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ); - - - OAuthManager.RegisterClient _ - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - - OAuthManager.RegisterClient _ - ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - - - You can register multiple clients to a single provider. - The following example shows how to do it. - - - var clientName = ClientName.Create("Debug", "Facebook"); - - OAuthManager.RegisterClient - ( - clientName - "000000000000000000", - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - ); - - clientName = ClientName.Create("Any name", "Facebook"); - - OAuthManager.RegisterClient - ( - clientName - "111111111111111111", - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - ); - - - Dim name As ClientName = ClientName.Create("Debug", "Facebook") - - OAuthManager.RegisterClient _ - ( - name, - "000000000000000000", - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - ) - - name As ClientName = ClientName.Create("Any name", "Facebook") - - OAuthManager.RegisterClient _ - ( - name, - "111111111111111111", - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - ) - - - - - - Checks registered provider with the specified name or not. - - The provider name or client name. - - - - Returns type of client by name. - - The provider name. - - - - Gets the list of all clients. - - - - - Gets the list of active requests. - - - - - Gets the list of registered clients. - - - - - OAuth client for Tumblr. - - -

Register and Configure a Tumblr Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Tumblr Dashboard, and Register an application. - - In the application settings you can found Consumer Key and Consumer Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new TumblrClient - ( - "2EZbsj2oF8OAouPlDWSVnESetAchImzPLV4q0IcQH7DGKECuzJ", - "4WZ3HBDwNuz5ZDZY8qyK1qA5QFHEJY7gkPK6ooYFCN4yw6crKd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New TumblrClient _ - ( - "2EZbsj2oF8OAouPlDWSVnESetAchImzPLV4q0IcQH7DGKECuzJ", - "4WZ3HBDwNuz5ZDZY8qyK1qA5QFHEJY7gkPK6ooYFCN4yw6crKd" - ) - ) - - - For more details, please visit Tumblr API Documentation. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Consumer Key obtained from the Tumblr Dashboard. - The Consumer Secret obtained from the Tumblr Dashboard. - - - - Gets an user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Tumblr. - - - - - OAuth client for SourceForge. - - -

Register a SourceForge Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Consumer ID and Consumer Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the SourceForge Authorized Applications and Register New Application. - - You can see Consumer Key and Consumer Secret, use this for creating an instance of the . - - - OAuthManager.RegisterClient - ( - new SourceForgeClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New SourceForgeClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - - - For more details, please visit Allura API. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Consumer Key obtained from the SourceForge OAuth applications. - The Consumer Secret obtained from the SourceForge OAuth applications. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - Name of the user whose data should be obtained. - - - - Gets the request token from the remote server. - - - - - Gets the access token from the remote server. - - - - - Unique provider name: SourceForge. - - - - - OAuth client for Mail.Ru. - - - Mail.Ru is a popular email service, search engine, social network, photo & video hosting, blogs and another services in Russia and CIS. -

Register and Configure a Mail.Ru Site

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Unfortunately, the interface is only in Russian. - You must have a confirmed account in Mail.Ru. - Open Sites page and click Connect a New Site. - - Create a New Site button - - Accept the terms of the agreement. - - Terms - - Enter the site name, URL and click the Next button. - - Site name and URL - - Download the receiver.html file and place it in the root directory of your site. - This step can be skipped (Пропустить). - - receiver.html file - - The last step you will find the Client ID and Client Secret. - - Use this for creating an instance of the . - - - Cleint ID and Client Secret - - - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - - - For more details, please visit to the Mail.Ru API Documentation. - -
- -

Windows Forms

- The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Add a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // mail.ru client registration - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' mail.ru client registration - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - - Result of the program is shown in the images below. - Log in with Mail.Ru - Mail.Ru User Info -

ASP .NET MVC

- The following example shows how to use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - End Sub - - The MailRuLoginResult method will handle authorization result. - - public ActionResult MailRuLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function MailRuLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Mail.Ru. - - public ActionResult MailRuLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Mail.Ru", Url.Action("MailRuLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function MailRuLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Mail.Ru", Url.Action("MailRuLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the MailRuLogin method. - - @Html.ActionLink("Log in with Mail.Ru", "MailRuLogin") - - NOTE: For proper processing, you will need to download and put on your site a receiver.html file. -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID. - The Client Secret. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - The access token must contain the user ID in the parameter x_mailru_vid. - - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Mail.Ru. - - - - - Return URL. - - - - - Implements a file to transfer in a HTTP request. - - - - - Initializes a new instance of the class. - - Content of the file. - Name of the file. - The name of the parameter. - - - - Initializes a new instance of the class. - - The name of the parameter. - The posted file. - - - - Initializes a new instance of the class. - - Content of the file. - Name of the file. - The name of the parameter. - MIME type of the file. - - - - Gets or sets the filename. - - - - - Represents authorization results. - - - - - Initializes a new instance of the class. - - - - - The ID of the authorization request. - - - - - OAuth version. For example: 1.0, 2.0. - - - - - Provider and custom client name. - - - - - Provider name. For example: facebook, twitter, google. - - - - - The access token which is used to query the provider. - - - - - The user profile details that is returned from the provider. - - - - - Gets a value indicating whether the authorization is successful. - - - - - Gets error info when the authorization is not successful. - - - - - Gets the user ID that is returned from the provider. - - - - - Gets the username that is returned from the provider. - - - - - Gets the access token value. - - - - - Represents the access token exception. - - - - - Initializes a new instance of the class with a specified message. - - The error message that explains the reason for this exception. - - - - Represents the user profile info. - - - - - Initializes a new instance of the class. - - The data source. - The mapping rules. - - - - Initializes a new instance of the class. - - The data source. - The mapping rules. - - - - Returns the or . - - - - - Gets or sets a collection containing the API request results. - - - - - Gets or sets the user ID. - - - - - Gets or sets the username. - - - - - Gets or sets the first name of the user. - - - - - Gets or sets the last name of the user. - - - - - Gets or sets the display name of the user. - - - - - Gets or sets user email address. - - - - - Gets or sets user phone. - - - - - Gets or sets user birthday. - - - - - Gets or sets user url. - - - - - Gets or sets user image url. - - - - - Gets or sets gender of the user. - - - - - Gets the first and last name. - - - - - The exception that is thrown when a user fails to login. - - - - - Initializes a new instance of the class with a specified error message. - - The error message that explains the reason for this exception. - - - - OAuth client for Yahoo. - - -

Register and Configure a Yahoo Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Consumer ID and Consumer Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open Yahoo Developer Network and Create a Project. - - In the application settings you can found Consumer Key and Consumer Secret. - Use this for creating an instance of the class. - - Note that Yahoo! does not work with the localhost. Use only a real servers. Make sure that your application on the Yahoo! dashboard configured correctly. - Yahoo! has a pretty flimsy OAuth interface. If something is done or configured incorrectly, the work will be nothing. But in general, the client is tested and works. - - OAuthManager.RegisterClient - ( - new YahooClient - ( - "dj0yJmk9Qm1vZ3p2TmtQUm4zJmQ9WVdrOU4wbGlkWGxJTkc4bWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD0xZQ--", - "a55738627652db0acfe464de2d9be13963b0ba1f" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New YahooClient _ - ( - "dj0yJmk9Qm1vZ3p2TmtQUm4zJmQ9WVdrOU4wbGlkWGxJTkc4bWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD0xZQ--", - "a55738627652db0acfe464de2d9be13963b0ba1f" - ) - ) - - - For more details, please visit Yahoo Developer Network. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Consumer Key obtained from the Yahoo Developer Dashboard. - The Consumer Secret obtained from the Yahoo Developer Dashboard. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Access token must contain the user ID in the parameter xoauth_yahoo_guid. - - - - - Gets the access token from the remote server. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - (!) - To update the access token, you must specify the return address that was used in obtaining the access token. - - - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - An exception occurs if there is no authorization code. - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - Callback address that was used in obtaining the access token. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - (!) - To update the access token, you must specify the return address that was used in obtaining the access token. - - - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - An exception occurs if there is no authorization code. - - - - Unique provider name: Yahoo. - - - - - OAuth client for VK (VKontakte). - - - VK (VKontakte) is "Russian Facebook". :-) -

Register and Configure a VKontakte Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the VK App development and click Create an Application. - - Create an Application button - - Specify the application name and type, and click the Connect Application. - - Creating an application - - Confirm by SMS. - - Confirmation - - - In the Application Settings you can found Application ID and Secure key, this is Client ID and Client Secret. - Use this for creating an instance of the class. - - NOTE: Change application status to Application ON and visible to all. - - Application settings - - - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ) - - For web projects, enable Open API, set Site address and configure Base domain in the Open API section. - - Base domains - - - For more details, please see VK App development. - -
- -

Windows Forms

- The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Insert a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // vk(ontakte) client registration - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - // application id - "4457505", - // secure secret - "wW5lFMVbsw0XwYFgCGG0" - ) - { - // display=popup - to open a popup window - Parameters = new NameValueCollection { { "display", "popup" } } - } - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' vk(ontakte) client registration - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) With _ - { - .Parameters = New NameValueCollection() From {{"display", "popup"}} - } - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("vk")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("vk")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - - Result of the program is shown in the images below. - Log in with VK(ontakte) - VK User Info -

ASP .NET MVC

- The following example shows how to use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ) - End Sub - - The VkontakteLoginResult method will handle authorization result. - - public ActionResult VkontakteLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function VkontakteLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Vkontakte. - - public ActionResult VkontakteLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("vk", Url.Action("VkontakteLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function VkontakteLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("vk", Url.Action("VkontakteLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the VkontakteLogin method. - - @Html.ActionLink("Log in with VK(ontakte)", "VkontakteLogin") - -

ASP .NET WebForms

- The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkVkontakte" runat="server" - Text="Log in with VK(ontakte)" onclick="lnkVkontakte_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkVkontakte_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("vk", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkVkontakte_Click(sender As Object, e As EventArgs) Handles lnkVkontakte.Click - OAuthWeb.RedirectToAuthorization("vk", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Application ID obtained from the VK App development. - The Secure Key obtained from the VK App development. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - - Unique provider name: VK. - - - - - Return URL. - - - - - Represents the request token results. - - - - - Initializes a new instance of the class. - - The request result. - The address of the authorization. - The query parameters. Will be used in the formation of the authorization address. - - - - Returns the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets the OAuth token. - - - - - Gets the token secret. - - - - - The parameter is used to differentiate from previous versions of the protocol. - - - - - Gets the address of the authorization. - - - - - Collection of HTTP parameters. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - The collection of parameters. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Initializes a new instance of the class. - - The body of a request. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Initializes a new instance of the class. - - The body of a request. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Initializes a new instance of the class. - - The array of parameters. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Adds a parameter to the end of the collection. - - The parameter to be added to the collection. - - - - Adds a parameter to the end of the collection. - - The name of parameter. - The parameter value. - - - - Adds a to the end of the collection. - - The name of the parameter. - The parameter value. - - - - Adds a to the end of the collection. - - The name of the parameter. - The value of the parameter. - The type of the parameter. - - - - Adds a to the end of the collection. - - The name of parameter. - The posted file. - - - - Adds a to the end of the collection. - - The posted file. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The Content-Type of the file. - The content of the file. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The content of the file. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The Content-Type of the file. - The file stream. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The file stream. - - - - Adds a to the end of the collection. - - The content of the request. - - - - Adds a to the end of the collection. - - The content of the request. - - - - Adds a to the end of the collection. - - The content of the request. - - - - Adds the items of the specified collection to the end of the current instance of the . - - The collection whose items should be added to the end of the current instance of the . - - - - Adds a to the end of the collection. - - The name of parameter. - The parameter value. - - - - Adds a to the end of the collection. - - The name of parameter. - The parameter value. - - - - Adds file as content to the end of the collection. - - The posted file. - - - - Adds content to the end of the collection. - - The Content-Type of the . - The content value. - - - - Inserts an element into the instance of the at the specified index. - - The zero-based index at which item should be inserted. - The to insert. - - - - Inserts the elements of a collection into the instance of the at the specified index. - - The zero-based index at which the new elements should be inserted. - The collection whose elements should be inserted into the instance of the . - - - - Removes the first occurrence of a specific parameter from the . - - The parameter to remove from the . - - true if is successfully removed; otherwise, false. - This method also returns false if was not found in the . - - - - - Removes all the elements that match the conditions defined by the specified predicate. - - The delegate that defines the conditions of the elements to remove. - The number of elements removed from the . - - - - Removes the element at the specified index of the . - - The zero-based index of the element to remove. - - - - Removes a range of elements from the . - - The zero-based starting index of the range of elements to remove. - The number of elements to remove. - - - - Removes all elements from the . - - - - - Updates status of the collection. - - - - - Checks parameters types. - - The type for checking. - - - - Returns a string query parameters encoded by default method (). - - - - - Returns a string of query parameters with a specified separator. - - The separator of query parameters. For example: & - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified separator and encoding parameters. - - The separator of query parameters. - The type of the encoder. - The types of parameters to be used. - - - - Copies elements of the to a new instance. - - The true value included into the results only the parameters. The default value is false - all parameters. - - - - Gets a body for the request. - - - - - Writes the parameters to the request. - - The instance of the request. - - - - Writes a file to the request. - - The name of the parameter. - The filename. - The Content-Type of the file. - The content of the file. - The output stream instance. - - - - Writes a form-data parameter to the request. - - The name of the parameter. - The value of the parameter. - The output stream instance. - - - - Writes any parameter to the request. - - The Content-Type of the . - The content value. - The instance of the output stream. - - - - The assignment operator for array of the . - - The array that will be used as the . - New instance of the . - - - - The assignment operator for the . - - The collection that will be used as the . - New instance of the . - - - - The assignment operator for the byte array. - - The byte array of the request body. - New instance of the . - - - - The assignment operator for the . - - The instance of the of the request body. - New instance of the . - - - - Gets a value indicating whether the current collection has a files. - - - - - Gets a value indicating whether the current collection has a . - - - - - Gets a boundary for a request. - - - - - Gets or sets code page for parameters encoding. - - - - - The exception that is thrown when adding a to the and collection has one a . - - - - - Initializes a new instance of the . - - - - - OAuth client for Assembla. - - -

Register and Configure an Assembla Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - - Register a new OAuth application. - - In the application settings you can found Application ID and Application Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new AssemblaClient - ( - "bOS4QkXnmr5jhdacwqjQXA", - "701ee6dedf74fc4ad75bfa7476666a2f" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New AssemblaClient _ - ( - "bOS4QkXnmr5jhdacwqjQXA", - "701ee6dedf74fc4ad75bfa7476666a2f" - ) - ) - - - For more details, please visit Assembla API Documentation Site. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Application ID obtained from the Assembla Applications Manager. - The Application Secret obtained from the Assembla Applications Manager. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Assembla. - - - - - The for . - - - - - Initializes a new instance of the class. - - - - - Returns a collection of property descriptors for the object represented by this type descriptor. - - - - - The properties collection. - - - - - Implements a request body. - - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Represents a method that is called for parsing item of the API data. - - The instance to parse. - - - - References a method to be called when a corresponding asynchronous web request completes. - - The result of the asynchronous web request. - - - - Represents data mapping item for API results. - - - - - Initializes a new instance of the class. - - - - - Gets or sets the key name in the data source. - - - - - Gets or set the property name in the destination object. - - - - - Gets or sets the data type of the property in the destination object. - - - - - Gets or sets the data format. - - - - - Gets or sets a custom parser of the data. - - - - - Represents the request item to OAuth server. - - - - - Initializes a new instance of the class. - - The instance of the OAuth client. - The client name. - - - - Gets name of the client. - - - - - Gets instance of the OAuth client. - - - - - Gets date and time creation of the request. - - - - - Represents a HTTP authorization header. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with specific authorization type and value. - - - - - Initializes a new instance of the class from specific source. - - - - - Removes the value with the specified key from the . - - The key of the element to remove. - - true if the element is successfully found and removed; otherwise, false. - This method returns false if key is not found in the or is not collection. - - - - - Returns OAuth string of the current object for Authorization header. - - - - - Invoked before sending a web request. - - HTTP Method of the request: POST, PUT, GET or DELETE. - URL of the web request. - The value of the Content-Type HTTP header. - >Parameters of the web request. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Gets or sets authorization method. - - - - - Gets or sets parameters of the authorization. - - - - - Authorization parameters. - - - - - Sorted authorization parameters. - - - - - Gets or sets the value associated with the specified key. - - The key of the value to get or set. - - - - The list of access token types. - - - - - Bearer - - - - - OAuth - - - - - Represents the name of the client. - - - - - Initializes a new instance of the . - - The provider name. - - - - Initializes a new instance of the . - - The client name. Any string. - The provider name. - - - - Returns a new instance with a specified . - - - - - Returns a new instance with a specified and . - - - - - Converts a specified string to . - - The string to parse. - - - - Encodes a string. - - The string to encode. - - - - Decodes a string. - - The string to decode. - - - - Escapes a special characters in a string. - - The string to escape. - - - - Converts any escaped characters in the input string. - - The input string containing the value to convert. - - - - Returns a string that represents the current . - - - - - Determines whether two object instances are equal. - - The object to compare with the current instance of the . - true if the specified object is equal to the current ; otherwise, false. - - - - Determines whether two object instances are equal. - - The instance of to compare with the current instance of the . - true if the specified instance is equal to the current ; otherwise, false. - - - - Serves as a hash function for a particular type. - - A hash code for the current . - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Indicate whether two are not equal. - - The first instance. - The second instance. - - - - Indicate whether two are equal. - - The first instance. - The second instance. - - - - Gets the client name. - - - - - Gets the provider name. - - - - - Gets a md5 hash code for the current instance of the . - - - - - Represents the collection of the . - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the with a specified reference to parent. - - - - - Initializes a new instance of the by other an instance of the . - - - - - Adds the specified key and value to the collection. - - The key of the element to add. - The value of the element to add. - - - - Determines whether the collection contains the specified key. - - The key to locate in the collection. - is null. - - - - Removes the value with the specified key from the collection. - - The key of the element to remove. - - true if the element is successfully found and removed; otherwise, false. - - - - - Returns a string that represents the current . - - - - - Determines whether two object instances are equal. - - The object to compare with the current instance of the . - true if the specified object is equal to the current ; otherwise, false. - - - - Returns a string that represents the specified item of the . - - The item to converted. - - - - Returns a string that represents the specified instance. - - The value to converted. - - - - Adds the specified item to the . - - The item to add. - - - - Removes all items from the collection. - - - - - Determines whether the collection contains a specific value. - - The object to locate in the collection. - - - - Removes the first occurrence of a specific object from the collection. - - The object to remove from the collection. - - - - Gets the value associated with the specified key. - - The key whose value to get. - When this method returns, the value associated with the specified key, if the key is found; otherwise, the . - - - - [Is not implemented] Copies the elements of the collection to an , starting at a particular index. - - The one-dimensional that is the destination of the elements copied from collection. The must have zero-based indexing. - The zero-based index in array at which copying begins. - - - - Returns an enumerator that iterates through a collection. - - - - - Returns an enumerator that iterates through a collection. - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Returns instance from . - - The value from which will be returned the . - - - - Gets or sets items of the collection. - - - - - The reference to parent. - - - - - Gets or sets the value associated with the specified key. - - The key of the value to get or set. - - - - Gets or sets the element at the specified index. - - The zero-based index of the element to get or set. - - - - Gets a collection containing the keys in the collection. - - - - - Gets a collection containing the values in the collection. - - - - - Gets the number of elements contained in the collection. - - - - - Gets a collection containing the keys in the collection. - - - - - Gets a collection containing the values in the collection. - - - - - Gets a value indicating whether the collection is read-only. Always false. - - - - - Represents property description of a class. - - - - - The data reader. - - - - - Initializes a new instance of the class. - - - - - Returns whether resetting an object changes its value. - - The component to test for reset capability. - - - - Gets the current value of the property on a component. - - The component with the property for which to retrieve the value. - - - - Resets the value for this property of the component to the default value. - - The component with the property value that is to be reset to the default value. - - - - Sets the value of the component to a different value. - - The component with the property value that is to be set. - The new value. - - - - Determines a value indicating whether the value of this property needs to be persisted. - - The component with the property to be examined for persistence. - - - - Gets a value indicating whether this property is read-only. - - - - - Gets the type of the property. - - - - - Gets the type of the component this property is bound to. - - - - - Represents helper class for sessions management of OAuth. - - - Mainly the class is intended for web projects. - But you can use some methods of the class in desktop applications together with the WebBrowser control. - - The methods , - , - and - - will not work in desktop applications. - - - -

ASP .NET WebForms

- The following example shows how to use the in ASP .NET WebForms. - To redirect the user to the login page is used the method. - Processing of the authorization results is performed by . - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkTwitter" runat="server" - Text="Log in with Twitter" onclick="lnkTwitter_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkTwitter_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Twitter", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkTwitter_Click(sender As Object, e As EventArgs) Handles lnkTwitter.Click - OAuthWeb.RedirectToAuthorization("Twitter", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - -

Windows Forms

- The following example shows how to use the in desktop applications. - Methods redirection in Windows Forms applications do not work. To get the address of the authorization is used. - To test the example, create a new Windows Forms project with two forms. Add a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // mail.ru client registration - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' mail.ru client registration - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - -
-
- - - Redirects current client to the authorization page of the specified provider. - - Provider name, through which it is necessary to authorize the current user. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider with specified parameters. - - Provider name, through which it is necessary to authorize the current user. - Additional parameters to be passed to the authorization query. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider, query parameters and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - Additional parameters to be passed to the authorization query. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider, query parameters and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - Additional parameters to be passed to the authorization query. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Returns the authorization URL of the specified provider. - - Provider name, through which it is necessary to authorize the current user. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider with specified parameters. - - Provider name, through which it is necessary to authorize the current user. - Additional parameters to be passed to the authorization URL. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider, query parameters and return URL. - - Provider name, through which it is necessary to authorize the current user. - Additional parameters to be passed to the authorization URL. - The address to which the user is redirected after the authorization. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider, query parameters and return URL. - - - The provider name, through which it is necessary to authorize the current user; or the name of the registered client. - - Additional parameters to be passed to the authorization URL. - The address to which the user is redirected after the authorization. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Verifies the authorization results for the current URL. - - - The method will not work in desktop applications. For desktop applications you can use the overloads or . - - - Returns the verification results. - - - - - Verifies the authorization results for the specified URL. - - Address at which to perform the verification. - - Returns the verification results. - - - - - Verifies the authorization results for the specified request identifier and the code of the authorization. - - Request identifier. - The authorization code received from the provider server. - - Returns the verification results. - - - This method is intended for internal use. It is recommended to use the overload or . - - - - - Verifies the authorization results for the current URL and removes the request from memory. - - - The method will not work in desktop applications. For desktop applications you can use the overloads or . - - - Returns the verification results. - - - - - Verifies the authorization results for the specified URL, and removes the request from memory. - - Address at which to perform the verification. - - Returns the verification results. - - - - - Verifies the authorization results for the specified request identifier and the code of the authorization, and removes the request from memory. - - Request identifier. - The authorization code received from the provider server. - - Returns the verification results. - - - This method is intended for internal use. It is recommended to use the overload or . - - - - - OAuth client for Odnoklassniki. - - - Odnoklassniki is a social network service for classmates and old friends. It is popular in Russia and CIS. -

Register and Configure a Odnoklassniki Site

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open My Games page and click My Uploaded Games. - - My Games in the footer menu - - - My Uploaded Games - - Click Add App. - - Add App button - - Enter the Title, Shortname, Description, Image link and App link. Select Application type (External type) and Permission. - - - (!) - - It is important to provide a link to the application (App link).
- You must use this link as the return URL. Even for desktop applications.
- You can use localhost for desktop applications.
- It is important to specify the type of application: External. -
-
-
- - App form - - In your email box you will find email message with the Client ID, Client Secret and Public key. - - Email message - - - Use this for creating an instance of the . - - - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ) - - - For more details, please visit to the Odnoklassniki API Documentation. - -
- -

Windows Forms

- The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Add a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // odnoklassniki client registration - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - // application ID - "1094959360", - // sectet key - "E45991423E8C5AE249B44E84", - // public key - "CBACMEECEBABABABA" - ) { ReturnUrl = "http://localhost" } // return url - it's important - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' odnoklassniki client registration - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) With { .ReturnUrl = "http://localhost" } - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Odnoklassniki")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Odnoklassniki")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - -

ASP .NET MVC

- The following example shows how to use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - // application ID - "1094959360", - // sectet key - "E45991423E8C5AE249B44E84", - // public key - "CBACMEECEBABABABA" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ) - End Sub - - The OdnoklassnikiLoginResult method will handle authorization result. - - public ActionResult OdnoklassnikiLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function OdnoklassnikiLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Odnoklassniki. - - public ActionResult OdnoklassnikiLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Odnoklassniki", Url.Action("OdnoklassnikiLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function OdnoklassnikiLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Odnoklassniki", Url.Action("OdnoklassnikiLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the OdnoklassnikiLogin method. - - @Html.ActionLink("Log in with Odnoklassniki", "OdnoklassnikiLogin") - -

ASP .NET WebForms

- The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - // application ID - "1094959360", - // sectet key - "E45991423E8C5AE249B44E84", - // public key - "CBACMEECEBABABABA" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - Response.Write(String.Format("Email: {0}", user.Email)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Response.Write(String.Format("Email: {0}", user.Email)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkOdnoklassniki" runat="server" - Text="Log in with Odnoklassniki" onclick="lnkOdnoklassniki_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkOdnoklassniki_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Odnoklassniki", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkOdnoklassniki_Click(sender As Object, e As EventArgs) Handles lnkOdnoklassniki.Click - OAuthWeb.RedirectToAuthorization("Odnoklassniki", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID. - The Client Secret. - The Public Key. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - - Unique provider name: Odnoklassniki. - - - - - Public Key for access to API. - - - - - The list of the types a HTTP parameters. - - - - - Unformed parameter. - - - - - Parameter of the query string. - - - - - Parameter of the form. - - - - - File. - - - - - Body of the request. - - - - - OAuth client for Instagram. - - -

Register and Configure a Instagram Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Register as Developer and Register new Client ID. - - In the application settings you can found Client ID and Client Key. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new InstagramClient - ( - "215a1941ebed4e4fa74e94dd84762836", - "ba53a710e1624870bc066e7a9ae38601" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New InstagramClient _ - ( - "215a1941ebed4e4fa74e94dd84762836", - "ba53a710e1624870bc066e7a9ae38601" - ) - ) - - - For more details, please visit Instagram Developer Documentation. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the Instagram Manage Clients. - The Client Secret obtained from the Instagram Manage Clients. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Instagram. - - - - - OAuth client for Yandex. - - - Yandex is a popular search engine in Russia and CIS. -

Register and Configure a Yandex Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the register new application page, fill out the form and click Save. - NOTE: Russian language is available on the yandex.ru - Specify the application name and set permissions. - - To access a users profile, select Yandex.Username: Date of birth; Email address; User name, surname and gender. - This minimum permissions that are required to work. - - For web project, set a Callback URI. - NOTE: For desktop applications set Callback URI to https://oauth.yandex.ru/verification_code. - - Register new application - - - In the next step you will see an Application ID and Application password, this is Client ID and Client Secret. - Use this for creating an instance of the . - - - Client ID and Client Secret - - - OAuthManager.RegisterClient - ( - new YandexClient - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New YandexClient _ - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ) - - - For more details, please visit Yandex OAuth Documentation. - -
- -

Console Applications

- The following example shows how to use the in Console Applications. - For desktop applications, the user will need to manually enter authorization code. - - class Program - { - static void Main(string[] args) - { - try - { - var yandex = new YandexClient - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ); - - // open the login page in browser - System.Diagnostics.Process.Start(yandex.AuthorizationUrl); - - // waiting of entering the access code - string code = ""; - while (String.IsNullOrEmpty(code)) - { - Console.WriteLine("Enter access code:"); - code = Console.ReadLine(); - } - - Console.WriteLine(); - - // set authorization code - yandex.AuthorizationCode = code; - // get user info - var user = yandex.GetUserInfo(); - Console.WriteLine("User ID: {0}", user.UserId); - Console.WriteLine("E-Mail: {0}", user.Email); - Console.WriteLine("Name: {0}", user.DisplayName); - Console.WriteLine("Birthday: {0}", user.Birthday); - Console.WriteLine("Sex: {0}", user.Sex); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - Console.ReadKey(); - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Module Module1 - - Sub Main() - Try - Dim yandex As New YandexClient _ - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ' open the login page in browser - System.Diagnostics.Process.Start(yandex.AuthorizationUrl) - - ' waiting of entering the access code - Dim code As String = "" - Do While String.IsNullOrEmpty(code) - Console.WriteLine("Enter access code:") - code = Console.ReadLine() - Loop - - ' set authorization code - yandex.AuthorizationCode = code - - ' get user info - Dim user As UserInfo = yandex.GetUserInfo() - Console.WriteLine("User ID: {0}", user.UserId) - Console.WriteLine("E-Mail: {0}", user.Email) - Console.WriteLine("Name: {0}", user.DisplayName) - Console.WriteLine("Birthday: {0}", user.Birthday) - Console.WriteLine("Sex: {0}", user.Sex) - Catch ex As Exception - Console.WriteLine(ex.Message) - End Try - Console.ReadKey() - End Sub - - End Module - - Result of the program is shown in the images below. - Log in with Yandex - Access code - User info -

ASP .NET WebForms

- In a web projects you can use the and . - The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new YandexClient - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New YandexClient _ - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("E-Mail: {0}<br />", user.Email)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("E-Mail: {0}<br />", user.Email)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkYandex" runat="server" - Text="Log in with Yandex" onclick="lnkYandex_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkYandex_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Yandex", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkYandex_Click(sender As Object, e As EventArgs) Handles lnkYandex.Click - OAuthWeb.RedirectToAuthorization("Yandex", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - - NOTE: Do not forget to adjust the Callback URI in the Yandex Application Settings. -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Application ID. - The Application Password. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Unique provider name: Yandex. - - - - - Return URL. - - - - - Represents authorization parameters for OAuth 1.0. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with specific value. - - - - - Updates the nonce and the timestamp. - - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The query parameters. - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The query parameters. - - - - Gets or sets the consumer key. - - - - - Gets or sets the consumer secret. - - - - - Gets or sets the token. - - - - - Gets or sets the secret token. - - - - - Gets or sets the signature method. - - - - - Gets or sets the nonce. - - - - - Gets or sets the timestamp. - - - - - Gets or sets the version of the OAuth. - - - - - Gets or sets the signature. - - - - - Gets or sets the callback address. - - - - - Gets or sets the verifier code. - - - - - Represents the authorization grant type. - - - - - Using an authorization code to confirm the identity (grant type is authorization_code). - - - - - Using username and password (grant type is password). - - - - - Using basic authorization with username and password (grant type is client_credentials). - - - - - Using a token to refreshing the access token (grant type is refresh_token). - - - - - Initializes a new instance with a specified . - - The value of grant type. - - - - Returns a string that represents the current . - - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Gets or sets the value. - - - - - Gets a value indicating whether the current value is authorization_code or not. - - - - - Gets a value indicating whether the current value is password or not. - - - - - Gets a value indicating whether the current value is client_credentials or not. - - - - - The exception that is thrown when has more than one . - - - - - Initializes a new instance of the . - - - - - The exception that is thrown when a resource owner or authorization server denied the request. - - - - - Initializes a new instance of the class with a specified error message and the exception that is the cause of this exception. - - The error message that explains the reason for this exception. - - - - Represents the error results of the query. - - - - - Initializes a new instance of the class. - - The request results. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets a value indicating whether the current request result is successful or not. - - Always has the value false. - - - - OAuth client for Facebook. - - -

Register and Configure a Facebook Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - You need to register as developer. - - Open the Facebook Developers and Create a New App. - - Create new application menu - - Specify the application name and click the Create App. - - Create new application form - - - In the application dashboard you can found App ID and App Secret, this is Client ID and Client Secret. - Use this for creating an instance of the class. - - - App ID and App Secret - - - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - You can use the App ID and App Secret for desktop, mobile and web projects. -

The application availability

- - To manage the status of the application, you must provide contact information. - - - Enter a contact email on the Settings page. - - - Contact Email - - - And now, you can change availability status of the application on the Status & Review page. - - - Make App Public - -

Configure application for web projects

- For web projects, configure return URLs. - - Open the application Settings and click Advanced tab. - - - Advanced tab - - - You must add the return URLs to the Valid OAuth redirect URIs field of the Security section. - - Do not forget to save your changes. - NOTE: If the application will be used for web and desktop, then also add URL: https://www.facebook.com/connect/login_success.html. - NOTE: Enable Client OAuth Login if it's disabled. - - Valid OAuth redirect URIs - - - For more details, please see Facebook Developer Documentation. - -
- - The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Insert a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // facebook client registration - OAuthManager.RegisterClient - ( - new FacebookClient - ( - // app id - "1435890426686808", - // app secret - "c6057dfae399beee9e8dc46a4182e8fd" - ) - { - // display=popup - to open a popup window - Parameters = new NameValueCollection { { "display", "popup" } } - } - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' facebook client registration - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) With _ - { - .Parameters = New NameValueCollection() From {{"display", "popup"}} - } - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Insert a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("facebook")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("facebook")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - - Result of the program is shown in the images below. - Log in with Facebook - Facebook User Info - - - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The App ID obtained from the Facebook Developers. - The App Secret obtained from the Facebook Developers. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - For more details, please see User method in Guide of Facebook Graph API. - - - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Unique provider name: Facebook. - - - - - Return URL. - - - - - OAuth client for GitHub. - - -

Register and Configure a GitHub Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - - Register a new OAuth application. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new GitHubClient - ( - "e14122695d88f5c95bce", - "cde23ec001c5180e01e865f4efb57cb0bc848c16" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New GitHubClient _ - ( - "e14122695d88f5c95bce", - "cde23ec001c5180e01e865f4efb57cb0bc848c16" - ) - ) - - - For more details, please see GitHub Development Guides. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the GitHub Applications. - The Client Secret obtained from the GitHub Applications. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: GitHub. - - - - - Provides helpers methods for OAuth. - - - - - Unreserved characters for the method. - - - http://tools.ietf.org/html/rfc3986#page-13 - - - - - This is main helper class. - - - - - Percent encoding. - - The text to encode. - The object that specifies the encoding scheme. - - For more details, please see: - - - - - - - - - Percent encoding. - - The text to encode. - - - - Encodes a URL string using the specified encoding object. - - The text to encode. - The type of the encoder. - - - - Encodes a URL string using the specified encoding object. - - The text to encode. - The object that specifies the encoding scheme. - The type of the encoder. - - - - Encodes a string into JavaScript string. - - The string to encode. - - - - Generate timestamp for a signature (only for OAuth 1.0). - - - - The timestamp value MUST be a positive integer. Unless otherwise - specified by the server's documentation, the timestamp is expressed - in the number of seconds since January 1, 1970 00:00:00 GMT. - - For more details, please see: - - - - - Generate random key. - - - - - Compute MD5 hash. - - Value that must be processed. - - - - Converts the string value to its equivalent string representation that is encoded with base-64 digits. - - A composite format string for encoding to Base64. - An object array that contains zero or more objects to format. - The string representation, in base 64. - - - - Performs a request using a GET method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request using a POST method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for web request. - The value of the Content-Type HTTP header. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request using a PUT method. - - URL to which will be sent to the request. - Parameters to be passed to the request. - Authorization header value. - HTTP headers for the request. - The value of the Content-Type HTTP header. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request using a DELETE method. - - URL to which will be sent to the request. - Parameters to be passed to the request. - Authorization header value. - HTTP headers for the request. - Access token to be used in the request. - Returns an instance of the class, which contains the result of the request. - - Can not be used simultaneously and . Use only one of these parameters. - - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request. - - HTTP Method: POST (default), PUT, GET or DELETE. - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for web request. - The value of the Content-Type HTTP header. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Reads results of the web request to the string. - - instance. - - - - Performs an async request using a GET method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request using a POST method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - The value of the Content-Type HTTP header. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request using a PUT method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - The value of the Content-Type HTTP header. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request using a DELETE method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request. - - HTTP Method: POST (default), PUT, GET or DELETE. - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - The value of the Content-Type HTTP header. - A delegate that, if provided, is called when an async web request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Gets the value of the specified , if the is a . - - Source of data. - The key is to be obtained. - - - - Returns a string containing a number. - - The value for processing. - - - - Gets signature for the current request. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - The authorization parameters. - - - - Gets signature for the current request. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - The authorization parameters. - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Very sexy list. - - - - - No sex. - - :o) - - - - Male. - - - - - Female. - - - - - Programmer. - - - - - Deep Thought. - - - - - The list of authorization type. - - - - - Basic - - - - - Bearer - - - - - Digest - - - - - OAuth - - - - - OAuth client for Foursquare. - - -

Register and Configure a Foursquare Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Foursquare App and Create app. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new FoursquareClient - ( - "LHYZN1KUXN50L141QCQFNNVOYBGUE3G3FCWFZ3EEZTOZHY5Q", - "HWXYFLLSS2IUQ0H4XNCDAZEFZKIU3MZRP5G55TNBDHRPNOQT" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New FoursquareClient _ - ( - "LHYZN1KUXN50L141QCQFNNVOYBGUE3G3FCWFZ3EEZTOZHY5Q", - "HWXYFLLSS2IUQ0H4XNCDAZEFZKIU3MZRP5G55TNBDHRPNOQT" - ) - ) - - - For more details, please visit Foursquare for Developers. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the Foursquare Apps. - The Client Secret obtained from the Foursquare Apps. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Foursquare. - - -
-
diff --git a/bin/net35/Nemiro.OAuth.dll b/bin/net35/Nemiro.OAuth.dll deleted file mode 100644 index 7aba4dd8f381e763dc94923adb6a7fc1f7a833dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126464 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 - - - Nemiro.OAuth - - - - - The universal type that represents a value. - - - represents any type of data. - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the with a specified value. - - The value. - - - - Initializes a new instance of the with a specified value and attributes. - - The value. - The collection of an attributes. - - - - Initializes a new instance of the with a specified value and reference to parent. - - The value. - The instance of the . - - - - Initializes a new instance of the with a specified value, attributes and reference to parent. - - The value. - The collection of an attributes. - The instance of the . - - - - Copies items of the to a new Dictionary<string, object>. - - - A Dictionary<string, object> containing copies of the elements of the . - A null value, if the property is false or the is empty. - - - - - Copies items of the to a new . - - - A containing copies of the elements of the . - A null value, if the property is false or the is empty. - - - - - Returns a array that represents the current . - - - A array containing the current . - A null value, if the property and is false or the is empty. - - - - - Determines whether the contains the specified key. - - The key to locate in the . - true if the is not null and contains an element with the specified ; otherwise, false. - is null. - - - - Determines whether the contains the specified key. - - The key to locate in the . - true if the is not null and contains an element with the specified ; otherwise, false. - - - - Adds the specified key and value to the . - - The key of the element to add. - The value of the element to add. - - Returns the added element. - - - - If the current is not a collection ( is false), it will automatically be converted to the collection. - If the current is not empty, then it will be assigned a key ____ in a new collection. - - - - - - Adds the specified key and value to the . - - The key of the element to add. - The value of the element to add. - The reference to parent of the elemet to add. - - Returns the added element. - - - - If the current is not a collection ( is false), it will automatically be converted to the collection. - If the current is not empty, then it will be assigned a key ____ in a new collection. - - - - - - Removes the value with the specified key from the . - - The key of the element to remove. - - true if the element is successfully found and removed; otherwise, false. - This method returns false if key is not found in the or is not collection ( is false). - - - - - Parses the and converts to . - - The reference to the collection, which will be placed the result of parsing . - The for parsing. - The reference to parent. - - - - Returns the of the specified attribute. - - The name of the attribute whose value you want to get. - - - - Returns parent for new instance of . - - - - - Initializes a new instance. - - - - - Initializes a new instance with a specified . - - The value. - - - - Initializes a new instance with a specified and . - - The value. - The collection of an attributes. - - - - Initializes a new instance with a specified and reference to . - - The value. - The instance of the . - - - - Initializes a new instance with a specified , and reference to . - - The value. - The instance of the . - The collection of an attributes. - - - - Initializes an empty instance with a specified and reference to . - - The collection of an attributes. - The instance of the . - - - - Converts the specified JSON string to an . - - A string containing a JSON data to parse. - A new instance. - is null. - The length exceeds the value of . - The recursion limit defined by was exceeded. - contains an unexpected character sequence. - is a dictionary type and a non-string key value was encountered. - includes member definitions that are not available on the target type. - It is not possible to convert to the target type. - - - - Converts the specified XML string to an . - - A string containing a XML data to parse. - A new instance. - is null. - - - - Converts the specified parameters string to an . - - A string containing an url parameters to parse. - A new instance. - contains an CR or LF characters. - - If is null or empty, the function returns an instance. - - - - - Converts the specified JSON string to an . A return value indicates whether the conversion succeeded. - - A string containing a JSON data to parse. - If successful, this parameter takes the result of parsing data. - true if s was converted successfully; otherwise, false. - - - - Converts the specified XML string to an . A return value indicates whether the conversion succeeded. - - A string containing a XML data to parse. - If successful, this parameter takes the result of parsing data. - true if s was converted successfully; otherwise, false. - - - - Converts the specified url parameters string to an . A return value indicates whether the conversion succeeded. - - A string containing an url parameters to parse. - If successful, this parameter takes the result of parsing data. - true if s was converted successfully; otherwise, false. - - - - Indicates whether the specified value is null or an . - - The instance to test. - true if the parameter is null or is false; otherwise, false. - - - - Gets the underlying type code of the . - - - - - - Converts the value of this instance to an equivalent value using the specified culture-specific formatting information. - - An object that supplies culture-specific formatting information. - A value equivalent to the value of this instance. - - - - - - Converts the value this instance to an equivalent 8-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 8-bit unsigned integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent Unicode character using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A Unicode character equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A instance equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent number using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A number equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent double-precision floating-point number using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A double-precision floating-point number equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 16-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 16-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 32-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 32-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 64-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 64-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 8-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 8-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent single-precision floating-point number using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A single-precision floating-point number equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A instance equivalent to the value of this instance. - - - - Converts the value of this instance to an of the specified that has an equivalent value, using the specified culture-specific formatting information. - - The to which the value of this instance is converted. - An interface implementation that supplies culture-specific formatting information. - An instance of type whose value is equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 16-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 16-bit unsigned integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 32-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 32-bit unsigned integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 64-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 64-bit unsigned integer equivalent to the value of this instance. - - - - Creates a new object that is a copy of the current instance. - - A new object that is a copy of this instance. - - - - Returns an enumerator that iterates through a collection. - - An object that can be used to iterate through the collection. - - - - Returns an enumerator that iterates through a collection. - - An System.Collections.IEnumerator<UniValue> object that can be used to iterate through the collection. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Serves as a hash function for a particular type. - - A hash code for the current . - - - - Returns a string that represents the current . - - - - - Determines whether two object instances are equal. - - The object to compare with the current instance of the . - true if the specified object is equal to the current ; otherwise, false. - - - - Determines whether two instances are equal. - - The to compare with the current instance of the . - true if the specified is equal to the current ; otherwise, false. - - - - Determines whether this instance and another specified object have the same value. - - The string to compare to this instance of the . - true if the value of the parameter is the same as this instance; otherwise, false. - - - - Determines whether this string and a specified object have the same value. A parameter specifies the culture, case, and sort rules used in the comparison. - - The string to compare to this instance. - One of the enumeration values that specifies how the strings will be compared. - true if the value of the parameter is the same as this instance; otherwise, false. - - - - Converts the as a . - - The instance. - - - - Converts the as a Dictionary<string, object>. - - The instance. - - - - Converts the as an array. - - The instance. - - - - Converts the as an array. - - The instance. - - - - Converts the as a array. - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from Dictionary<string, object>. - - The value from which will be created a new instance of the . - - - - Creates a new instance from array. - - The value from which will be created a new instance of the . - - - - Creates a new instance from array. - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Indicate whether two are not equal. - - The first instance. - The second instance. - - - - Indicate whether two are equal. - - The first instance. - The second instance. - - - - Indicate whether and are not equal. - - The instance. - The string. - - - - Indicate whether and are equal. - - The instance. - The string. - - - - Returns an that can be bound to a data source from an object that does not implement an itself. - - - - - Returns a collection of custom attributes for this instance of a component. - - - - - Returns the class name of this instance of a component. - - - - - Returns the name of this instance of a component. - - - - - Returns a type converter for this instance of a component. - - - - - Returns the default event for this instance of a component. - - - - - Returns the default property for this instance of a component. - - - - - Returns an editor of the specified type for this instance of a component. - - A that represents the editor for this object. - - - - Returns the events for this instance of a component using the specified attribute array as a filter. - - An array of type that is used as a filter. - - - - Returns the events for this instance of a component. - - - - - Returns the properties for this instance of a component using the attribute array as a filter. - - An array of type that is used as a filter. - - - - Returns the properties for this instance of a component. - - - - - Returns an object that contains the property described by the specified property descriptor. - - A that represents the property whose owner is to be found. - - - - Gets or sets the value. - - - - - Gets a collection of string keys and values of the current . - - - Has a null value, if the property is false. - - - - - Gets or sets an attributes of the XML item (only for XML). - - - - - Gets the value associated with the specified key of the . - - The key of the value to get. - - - - Gets the value associated with the specified index of the . - - The index of the value to get. - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to array. - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to numeric type. - - - - - Gets a value indicating whether the current object has a value. - - - - - Gets a value indicating whether the current object has an attributes (only for xml data type). - - - - - Gets the number of elements actually contained in the . - - - - - Gets or sets the key for the current item, if the current item included into the collection. - - - Assigned automatically when parsing data of JSON, XML or query string. - root for root elements. - value for . - ____ for new collections created by the developer manually. - - - - - The parent of the current item, if the current item included into the collection. - - - - - Gets or sets a value that indicates whether the data type of the is array. - - - This affects the representation of the object as a string. For arrays in a JSON is not use the . - - - - - Gets or sets a value that indicates whether the type is unreferenced. - - - - - Represents the empty . - - - - - Gets a value indicating whether the collection is a collection of objects. - - - - - Implements a parameter of url. - - - - - Implements a HTTP paramter. - - - - - Initializes a new instance of the class. - - The name of the parameter. - The value of the parameter. - The content-type of the parameter. - - - - Initializes a new instance of the class. - - The name of the parameter. - The value of the parameter. - The type of the parameter. - The content-type of the parameter. - - - - Returns a string that represents the current parameter. - - - - - Gets or sets parameter name. - - - - - Gets or sets parameter value. - - - - - Gets or sets Content-Type. - - - - - Gets or sets type of the parameter. - - - - - Initializes a new instance of the class with a specified parameter name and value. - - The parameter value. - The parameter name. - - - - Represents a class that extends the class by adding methods for use with query parameters. - - - - - Convert the to list of the . - - The . - - - - Returns a string of query parameters without a separator. - - The . - - - - Returns a string of query parameters with a specified separator. - - The . - The separator of query parameters. For example: & - - - - Returns a string of query parameters with a specified encoding parameters. - - The . - Disables parameters encoding. - - - - Returns a string of query parameters with a specified separator and encoding parameters. - - The . - The separator of query parameters. - Disables parameters encoding. - - - - Sorts the by alphabetically and returns a new . - - The . - - - - Removes the value with the specified key from the . - - The . - The key of the element to remove. - - - - The exception occurs when you try to access a provider by provider name. If the name is incorrect, or does not exist. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with a specified error message. - - The error message that explains the reason for this exception. - An object array that contains zero or more objects to format. - - - - The exception that is thrown when trying to access an unregistered OAuth client. - - - Use the for OAuth clients registration. - - - The following example illustrates a situation in which the is thrown. - - string url = OAuthWeb.GetAuthorizationUrl("facebook"); - // ... - - - Dim url As String = OAuthWeb.GetAuthorizationUrl("facebook"); - ' ... - - ClientIsNotRegisteredException - To solve the problem enough to register the client. - - // facebook client registration - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - ' facebook client registration - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - Enjoy! - - string url = OAuthWeb.GetAuthorizationUrl("facebook"); - // ... - - - Dim url As String = OAuthWeb.GetAuthorizationUrl("facebook"); - ' ... - - - - - - Initializes a new instance of the class. - - - - - OAuth client for Google. - - -

Register and Configure a Google Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Google Developers Console and Create Project. - - Create new project button - - Enter the project name and click the Create. - - Create new project form - - - Click to the Credential menu in the APIs & OAuth. - - - Credential menu - - - For desktop application, click the Create new Client ID, select Installed application and Other. - - - Click the Create Client ID to complete. - - - Create new Client ID for desktop application - - - You will get the Client ID and Client Secret. - Use this for creating an instance of the . - - - Create new Client ID for desktop application - - - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - For web projects create another Client ID. In the form select the Web application and specify return addresses. - - Create new Client ID for web application - - - For more details, please visit Google Developers Console Help. - -
- - The following example shows how to use the in Console Applications. - For desktop applications, the user will need to manually enter authorization code. - - class Program - { - static void Main(string[] args) - { - try - { - var google = new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - // open the login page in browser - System.Diagnostics.Process.Start(google.AuthorizationUrl); - - // waiting of entering the access code - string code = ""; - while (String.IsNullOrEmpty(code)) - { - Console.WriteLine("Enter access code:"); - code = Console.ReadLine(); - } - - Console.WriteLine(); - - // set authorization code - google.AuthorizationCode = code; - // get user info - var user = google.GetUserInfo(); - Console.WriteLine("User ID: {0}", user.UserId); - Console.WriteLine("Name: {0}", user.DisplayName); - Console.WriteLine("Email: {0}", user.Email); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - Console.ReadKey(); - } - } - - - Module Module1 - - Sub Main() - Try - Dim google As New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ' open the login page in browser - System.Diagnostics.Process.Start(google.AuthorizationUrl) - - ' waiting of entering the access code - Dim code As String = "" - Do While String.IsNullOrEmpty(code) - Console.WriteLine("Enter access code:") - code = Console.ReadLine() - Loop - - ' set authorization code - google.AuthorizationCode = code - - ' get user info - Dim user As UserInfo = google.GetUserInfo() - Console.WriteLine("User ID: {0}", user.UserId) - Console.WriteLine("Name: {0}", user.DisplayName) - Console.WriteLine("Email: {0}", user.Email) - Catch ex As Exception - Console.WriteLine(ex.Message) - End Try - Console.ReadKey() - End Sub - - End Module - - Result of the program is shown in the images below. - Log in with Google - Access code - User info - In a web projects you can use the and . - The following example shows how use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-fscjqht7ou30a75gjkde1eu1brsvbqkn.apps.googleusercontent.com", - "SI5bIZkrSB5rO03YF-CdsCJC" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-fscjqht7ou30a75gjkde1eu1brsvbqkn.apps.googleusercontent.com", - "SI5bIZkrSB5rO03YF-CdsCJC" - ) - ) - End Sub - - The GoogleLoginResult method will handle authorization result. - - public ActionResult GoogleLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function GoogleLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Google. - - public ActionResult GoogleLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Google", Url.Action("GoogleLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function GoogleLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Google", Url.Action("GoogleLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the GoogleLogin method. - - @Html.ActionLink("Log in with Google", "GoogleLogin") - - - - - - - - - - - - - - - - - - - - - - -
- - - Represents base properties and method for OAuth 2.0 client. - - - For more details, please visit . - - - - - Represents base class for OAuth client classes. - - - - - Initializes a new instance of the class. - - The address for login. - The address for the access token. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - - is null or empty. - -or- - is null or empty. - -or- - is null or empty. - -or- - is null or empty. - - - - - Redirects a client to the Authorization URL. - - - Use this method only for web applications (ASP .NET). - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Gets the access token from the remote server. - - - This is method is implemented at the protocol level ( & ). - - The is null or empty. - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Gets the user details via API of the provider. - - May contain an access token, which will have to be used in obtaining information about the user. - - This is method is implemented at the client level. - - - - - Creates a shallow copy of the current object. - - The query parameters for new copy object. - The new return URL for new copy object. - A shallow copy of the current object. - - Method creates a copy of the current object, removes tokens, change the return address, query parameters and state. - Unfortunately, I made a mistake in architecture, so I had to make this method. - - - - - - Creates a shallow copy of the current object. - - A shallow copy of the current object. - - Method creates a copy of the current object, removes tokens, change the return address, query parameters and state. - Unfortunately, I made a mistake in architecture, so I had to make this method. - - - - - - Returns the specified access token or the current access token. - - May contain an access token, which will be refunded. - Indicates the need to check the parameter refresh_token in the access token. Default: false. - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - - - - Unique provider name. - - - Client classes are required to implement this property. - The provider name must be unique. - - - - public override string ProviderName - { - get - { - return "KGB"; - } - } - - - - - - Gets the endpoint of the authorization. - - - This property is implemented at the protocol level ( & ). - - - - - Gets or sets an access token. - - - - - Gets an access token value. - - - - - Gets or sets access code for access token requests. - - - - - Gets or sets unique request identifier. - For clients the value sets is automatically. - - - - - Gets or sets the application identifier. - - - - - Gets or sets the application secret key. - - - - - Gets or sets the base address for login. - - - - - Gets or sets the address for the access token. - - - - - Gets the version of the OAuth protocol. - - - - - Gets or sets return URL. - - - At this address provider will return the user authorization results. - For many providers are needed configuration of the application on the provider website. - - - - - Gets or sets additional query parameters. - - - These parameters will be transferred to the provider. - - - - - Gets or sets a value indicating whether the current client supports revoking access token. - - - - - Gets or sets a value indicating whether the current client supports refreshing access token. - - - - - Initializes a new instance of the class. - - The address for login. - The address for the access token. - The application identifier. - The application secret key. - - - - Gets the access token from the remote server. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - The scope of the access request. - - - - - The deault scope. - - - - - The separator in the scope list. - - - - - Gets or sets grant type. - - - - - Gets or sets username if is password or client_credentials. - - - - - Gets or sets password if is password or client_credentials. - - - - - Gets the endpoint of the authorization. - - - - - Initializes a new instance of the . - - The Client ID obtained from the Google Developers Console. - The Client Secret obtained from the Google Developers Console. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - In order to Google returned the refresh_token, when receiving an access token, you must specify access_type=offline. - - - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - { - Parameters = new NameValueCollection { { "access_type", "offline" } } - } - ); - - - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) With _ - { - .Parameters = New NameValueCollection() From {{"access_type", "offline"}} - } - ) - - For more details, please see Google Documentation. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Google. - - - - - Return URL. - - - - - Represents the empty results of the query. - - - The class is used to determine sends a request to the remote server or not. - - - - - Represents the base class for results of remote requests. - - - - - Initializes a new instance of the class. - - The request results. - - - - Initializes a new instance of the class. - - The content type of the response. - The source of the response. - - - - Initializes a new instance of the class. - - The content type of the response. - The source of the response. - The HTTP headers of the response. - The HTTP status code of the response. - - - - Parses the source to the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets or sets the HTTP status code of the output returned to the client. - - - - - Gets a value indicating whether the current request result is successful or not. - - - Successful result - is a response code from 200 to 299. - - - - - Gets or sets the content type of the response. - - - - - Gets or sets the http headers of the response. - - - - - Gets the Content-Disposition header of the response. - - - - - Gets the file name, if is file. - - - - - Gets or sets the source of the response. - - - - - Gets a value indicating the is file or not. - - - - - Gets a value indicating whether the is empty or not. - - - - - Gets or sets the processed result of the response. - - - - - Gets a value indicating the is or not. - - - - - Gets a value indicating the is or not. - - - - - Gets a value indicating the is XML or not. - - - - - Gets a value indicating the is array or not. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets a value indicating whether the current request result is successful or not. - - Always has the value false. - - - - Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. - - - - - Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. - - - - - Перезаписывает свойство CurrentUICulture текущего потока для всех - обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. - - - - - Поиск локализованного ресурса типа System.Drawing.Bitmap. - - - - - Ищет локализованную строку, похожую на Aleksey Sergeevich Nemiro is a Russian developer of applications and websites, - author of articles on programming and information technology. - - Aleksey was born on October 3, 1983 in the city of Vladivostok (Primorsky Krai, Russia). - In 2009, Aleksey migrated to the city of Yoshkar-Ola (Mari El, Russia). - - Started programming in 1998 on the G-Basic and QBasic. - - At various times worked with programming languages and technologies: - Visaul Basic, Delphi, C, Visual C++, Java, PHP, ASP VBScript and JScript [остаток строки не уместился]";. - - - - - The access token class for OAuth 1.0. - - - - - Represents base properties and method for access token results. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - Result of request to the OAuth server. - - - - Returns the . - - - - - Converts the specified string to an . - - A string containing an access token to parse. - A new instance. - - - - Converts the specified string to an . - - Type Inherited from the that should be returned. - A string containing an access token to parse. - A new instance. - - - - Indicates whether the specified value is null or an . - - The instance to test. - true if the parameter is null or is false; otherwise, false. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - The access token issued by the authorization server. - - - - - Represents the empty . - - - - - Gets a value indicating whether the is empty or not. - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Initializes a new instance of the class. - - Result of request to the OAuth server. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Returns the . - - - - - Converts the specified string to an . - - A string containing an access token to parse. - A new instance. - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - The access token issued by the authorization server. - - - - - The access token issued by the authorization server. - - - - - The access token class for OAuth 2.0. - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Initializes a new instance of the class. - - Result of request to the OAuth server. - - - - Initializes a new instance of the class with a specified access token and refresh token. - - The access token. - The refresh token. - - - - Initializes a new instance of the class with a specified access token and refresh token. - - The access token. - The refresh token. - The token type. For example: bearer. Default: null. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Returns the . - - - - - Converts the specified string to an . - - A string containing an access token to parse. - A new instance. - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - The access token issued by the authorization server. - - - - - The lifetime in seconds of the access token. - - - - - The refresh token, which can be used to obtain new - access tokens using the same authorization grant. - - - - - The scope of the access token. - - - - - The type of the token issued. Value is case insensitive. - - - - - The exception that is thrown when server of API returns error. - - - - - The exception that is thrown when an error occurs while accessing the network. - - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The content type of the server request result. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The content type of the server request result. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - The HTTP headers of the output. - The HTTP status code of the output. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Instance of the . - - - - - Gets the HTTP status code of the output returned to the client. - - - - - Gets the content type of the response. - - - - - Gets the http headers of the response. - - - - - Initializes a new instance of the class with a specified and the exception that is the cause of this exception. - - The result of the request. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class with a specified and error message. - - The result of the request. - The error message that explains the reason for this exception. - - - - Initializes a new instance of the class with a specified error message. - - The error message that explains the reason for this exception. - - - - Initializes a new instance of the class with a specified error message and the exception that is the cause of this exception. - - The error message that explains the reason for this exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - The content type of the server request result. - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - The content type of the server request result. - - - - Initializes a new instance of the class with a specified server request result, content type and a error message. - - The result of the request. - The error message that explains the reason for this exception. - The content type of the server request result. - - - - Initializes a new instance of the class with a specified server request result, content type and a error message. - - The result of the request. - The error message that explains the reason for this exception. - The content type of the server request result. - - - - OAuth client for Twitter. - - -

Register and Configure a Twitter Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Consumer ID and Consumer Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Twitter Application Management and Create a New App. - - Create a New App button - - Fill out the form and click the Create your Twitter application. - For web project, set a Callback URL. - - Create a New App form - - - Open the application page and click to the API Keys. - - - API Keys link - - - You can see API Key and API secret, this is Consumer Key and Consumer Secret. - Use this for creating an instance of the . - - - Client ID and Client Secret - - - OAuthManager.RegisterClient - ( - new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - - - For more details, please visit Twitter Developers Documentation. - -
- -

Console Applications

- The following example shows how to use the in Console Applications. - For desktop applications, the user will need to manually enter authorization code. - - class Program - { - static void Main(string[] args) - { - try - { - var twitter = new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ); - - // open the login page in browser - System.Diagnostics.Process.Start(twitter.AuthorizationUrl); - - // waiting of entering the access code - string code = ""; - while (String.IsNullOrEmpty(code)) - { - Console.WriteLine("Enter access code:"); - code = Console.ReadLine(); - } - - Console.WriteLine(); - - // set authorization code - twitter.AuthorizationCode = code; - // get user info - var user = twitter.GetUserInfo(); - Console.WriteLine("User ID: {0}", user.UserId); - Console.WriteLine("Name: {0}", user.DisplayName); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - Console.ReadKey(); - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Module Module1 - - Sub Main() - Try - Dim twitter As New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ' open the login page in browser - System.Diagnostics.Process.Start(twitter.AuthorizationUrl) - - ' waiting of entering the access code - Dim code As String = "" - Do While String.IsNullOrEmpty(code) - Console.WriteLine("Enter access code:") - code = Console.ReadLine() - Loop - - ' set authorization code - twitter.AuthorizationCode = code - - ' get user info - Dim user As UserInfo = twitter.GetUserInfo() - Console.WriteLine("User ID: {0}", user.UserId) - Console.WriteLine("Name: {0}", user.DisplayName) - Catch ex As Exception - Console.WriteLine(ex.Message) - End Try - Console.ReadKey() - End Sub - - End Module - - Result of the program is shown in the images below. - Log in with Twitter - Access code - User info -

ASP .NET WebForms

- In a web projects you can use the and . - The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkTwitter" runat="server" - Text="Log in with Twitter" onclick="lnkTwitter_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkTwitter_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Twitter", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkTwitter_Click(sender As Object, e As EventArgs) Handles lnkTwitter.Click - OAuthWeb.RedirectToAuthorization("Twitter", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - - NOTE: Do not forget to adjust the Callback URL in the Twitter Application Settings. -
- - - - - - - - - - - - - - - - - - - - -
- - - Represents base properties and method for OAuth 1.0 client. - - - For more details, please visit . - - - - - Initializes a new instance of the class. - - The address for the request token. - The address for login. - The address for the access token. - The application identifier. - The application secret key. - The name of hashing algorithm to calculate the signature: HMAC-SHA1 (default) or PLAINTEXT. - The is null or empty. - - - - Gets base string of the signature for current request. - - For more details, please visit - - - - Gets signature for the current request. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - - - - Gets the request token from the remote server. - - - - - Gets the access token from the remote server. - - - - - Gets or sets the address for the request token. - - - - - Get the authorization parameters. - - - - - Gets the endpoint of the authorization. - - - - - Gets or sets the request token. - - - - - Initializes a new instance of the . - - The API Key obtained from the Twitter Application Management. - The API Secret obtained from the Twitter Application Management. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Unique provider name: Twitter. - - - - - OAuth client for LinkedIn. - - -

Register and Configure a LinkedIn Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open and sigin to the LinkedIn for Developers, and Add new app. - - In the application settings you can found Api Key and Secret Key. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new LinkedInClient - ( - "75vufylz829iim", - "VOf14z4T1jie4ezS" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New LinkedInClient _ - ( - "75vufylz829iim", - "VOf14z4T1jie4ezS" - ) - ) - - - For more details, please visit LinkedIn for Developers. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Api Key obtained from the LinkedIn Dashboard. - The Secret Key obtained from the LinkedIn Dashboard. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: LinkedIn. - - - - - OAuth client for SoundCloud. - - -

Register and Configure a SoundCloud Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the SoundCloud for Developers and Register a new app. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new SoundCloudClient - ( - "42b58d31e399664a3fb8503bfcaaa9ba", - "f9d85648da59fb95ec131b40c7645c31" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New SoundCloudClient _ - ( - "42b58d31e399664a3fb8503bfcaaa9ba", - "f9d85648da59fb95ec131b40c7645c31" - ) - ) - - - For more details, please visit SoundCloud for Developers. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the SoundCloud Applications. - The Client Secret obtained from the SoundCloud Applications. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: SoundCloud. - - - - - Implements a form parameter. - - - - - Initializes a new instance of the class with a specified parameter name and value. - - The parameter value. - The parameter name. - - - - Represents data mapping collection for API results. - - - - - Initializes a new instance of the class. - - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - The data type. - The data format. For example: "dd.MM.yyyy" for dates, or: "00" for numerics, etc. - Custom parser of the data. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - The data type. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - The data type. - The data format. For example: "dd.MM.yyyy" for dates, or: "00" for numerics, etc. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - Custom parser of the data. - - - - The list of url encding methods. - - - - - Without encoding. - - - - - for POST requests when a conetent-type is x-www-form-urlencoded. - And for other requests. - - - - - x-www-form-urlencoded (spaces encoded as plus (+) signs). - - - - - RFC 3986 (spaces encoded as %20). - - - - - OAuth client for CodeProject. - - -

Register and Configure a CodeProject Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - - Register a new client. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new CodeProjectClient - ( - "92mWWELc2DjcL-6tu7L1Py6yllleqSCt", - "YJXrk_Vzz4Ps02GqmaUY-aSLucxh4kfLq6oq0CtiukPfvbzb9yQG69NeDr2yiV9M" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New CodeProjectClient _ - ( - "92mWWELc2DjcL-6tu7L1Py6yllleqSCt", - "YJXrk_Vzz4Ps02GqmaUY-aSLucxh4kfLq6oq0CtiukPfvbzb9yQG69NeDr2yiV9M" - ) - ) - - - For more details, please see CodeProject API Documentation. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the CodeProject Web API Clients. - The Client Secret obtained from the CodeProject Web API Clients. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: CodeProject. - - - - - OAuth client for Microsoft Live. - - -

Register and Configure a Live Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Live Connect App Management and Create a New Application. - - Create a New Application - - Specify the application name, read terms of use and click the I accept. - - Create a New Application form - - Open the App Settings and add return URLs. You can't use localhost. - - Redirect URLs - - On the App Settings page, you can found Client ID and Client Secret. - - Use this for creating an instance of the . - - - Cleint ID and Client Secret - - - OAuthManager.RegisterClient - ( - new LiveClient - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New LiveClient _ - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ) - - - For more details, please visit to the MSDN. - -
- - The following example shows how to add the Microsoft Live OAuth Client to ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new LiveClient - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New LiveClient _ - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ) - End Sub - - The LiveLoginResult method will handle authorization result. - - public ActionResult LiveLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function LiveLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Microsoft Live. - - public ActionResult LiveLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Live", Url.Action("LiveLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function LiveLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Live", Url.Action("LiveLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the LiveLogin method. - - @Html.ActionLink("Log in with Microsoft Live", "LiveLogin") - - Result shown in the images below. - Microsoft Live Sign in - User Info - - - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the Live Connect App Management. - The Client Secret obtained from the Live Connect App Management. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - In order to Microsoft Live returned the refresh_token, when receiving an access token, you must specify the scope wl.offline_access. - - - OAuthManager.RegisterClient - ( - new LiveClient - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - { - Scope = "wl.offline_access" - } - ); - - - OAuthManager.RegisterClient _ - ( - New LiveClient _ - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) With { .Scope = "wl.offline_access" } - ) - - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Live. - - - - - The exception that is thrown when HttpContext.Current is null (Nothing in Visual Basic). - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Initializes a new instance of the class. - - - - - The exception that is thrown when you attempt to register the already registered client. - - - - - Initializes a new instance of the class. - - The name of the provider. - - - - Initializes a new instance of the class. - - The name of the provider and client. - - - - Gets an error message. - - - - - OAuth client for Amazon. - - -

Register and Configure Amazon Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - You need to register as developer in the App Console. - - - Sign in to the App Console - - - In the App Console register new application. - - - Register new application - - - Specify one or more return URLs. Access to any other address will be denied. - - - NOTE: Amazon supports only addresses over HTTPS (excluding localhost). - - - For example: - - https://hamster.example.org/Home/ExternalLoginResult - http://localhost:59962/Home/ExternalLoginResult - http://localhost/ - - - - Allowed Return URLs - - Do not forget to save your changes. - Use application Client ID and Client Secret when creating an instance of the class. - - Allowed Return URLs - - - OAuthManager.RegisterClient - ( - new AmazonClient - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New AmazonClient _ - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ) - - - For more details, please see Amazon Developer Documentation. - -
- - The following example shows how to add the Amazon OAuth Client to ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new AmazonClient - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New AmazonClient _ - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ) - End Sub - - The ExternalLoginResult method will handle authorization result. - - public ActionResult ExternalLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function ExternalLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Now you can easily redirect user to login page. - - // NOTE: use httpS scheme for real websites - string authUrl = OAuthWeb.GetAuthorizationUrl("Amazon", Url.Action("ExternalLoginResult", "Home", null, null, Request.Url.Host)); - // for example, MVC redirection from Action: - // return Redirect(authUrl); - - - ' NOTE: use httpS scheme for real websites - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Amazon", Url.Action("ExternalLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - ' for example, MVC redirection from Action - ' Return Redirect(authUrl) - - Result shown in the images below. - Amazon Sign in - Amazon User Info - - - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the class. - - The client ID obtained from the App Console. - The client secret obtained from the App Console. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Amazon. - - - - - Additional type for references. - - - - - Represents the signature of the request. This is a helper class to simplify debugging. - - - - - Initializes a new instance of the class. - - The name of hashing algorithm to calculate the signature: HMAC-SHA1 (default) or PLAINTEXT. - The secret key for encryption. - Base string of the signature. - - is not suppored. - - - - - Returns the of the current object. - - - - - Gets the secret key for encryption. - - - - - Gets the name of hashing algorithm to calculate the signature: HMAC-SHA1 or PLAINTEXT. - - - - - Get base string of the signature. - - - - - Gets the signature. - - - - - Implements a value of the HTTP paramter. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Returns an encoded string of the value. - - - - - Returns an encoded string of the value. - - - - - Returns a string that represents the current value. - - - - - Returns a byte array that represents the current value. - - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the array of the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Gets or sets value. - - - - - OAuth client for Dropbox. - - -

Register and Configure a Dropbox Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Dropbox App Console and Create app. - Choose the Dropbox API app type. - - In the application settings you can found App key and App secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new DropboxClient - ( - "0le6wsyp3y085wy", - "48afwq9yth83y7u" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New DropboxClient _ - ( - "0le6wsyp3y085wy", - "48afwq9yth83y7u" - ) - ) - - - For more details, please visit Dropbox Platform Help. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The App key obtained from the Dropbox App Console. - The App secret obtained from the Dropbox App Console. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Unique provider name: Dropbox. - - - - - Variants of the signature encryption. - - - - - HMAC-SHA1 - - - - - RSA-SHA1 - - - - - PLAINTEXT - - - - - Represents helper class for management of OAuth clients. - - - You can use this class to register clients in your project. - - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Initializes the . - - - - - The method is called when the interval elapsed. - - Instance of the object that raised the event. - The event data. - - - - Adds the specified request to the collection. - - The unique request key. - The client name. - The client instance. - - - - Removes the request from collection. - - The unique request key to remove.. - - - - Registers the specified client in the application. - - The client instance. - is null or empty. - If you attempt to register the already registered client. - - - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Registers the specified client in the application. - - The client instance. - The any name of the client. For example: Test, Release, Project #1, Ku!, Example.org etc. - is null or empty. - If you attempt to register the already registered client. - - - OAuthManager.RegisterClient - ( - "Test", - new GoogleClient - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Test", - new FacebookClient - ( - "00000000000000", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - "Test", - New GoogleClient _ - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Test", - New FacebookClient _ - ( - "00000000000000", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Registers the specified client in the application. (the main method) - - The client instance. - The any name of the client. For example: Test, Release, Project #1, Ku!, Example.org etc. - is null or empty. - If you attempt to register the already registered client. - - - OAuthManager.RegisterClient - ( - "Test", - new GoogleClient - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Test", - new FacebookClient - ( - "00000000000000", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - "Test", - New GoogleClient _ - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Test", - New FacebookClient _ - ( - "00000000000000", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Registers the specified client in the application. - - The provider name. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - , or is null or empty. - Provider not found by . - - - OAuthManager.RegisterClient - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - OAuthManager.RegisterClient - ( - "facebook" - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ); - - - OAuthManager.RegisterClient _ - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - - OAuthManager.RegisterClient _ - ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - - - - - - Registers the specified client in the application. - - The provider name. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - List of scope that will be requested from the provider. Only for OAuth 2.0. - Additional parameters to be passed to the constructor of the client class. - Additional parameters that will be transferred to the provider website. - , or is null or empty. - Provider not found by . - The not suppored . - - - OAuthManager.RegisterClient - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - OAuthManager.RegisterClient - ( - "facebook" - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ); - - - OAuthManager.RegisterClient _ - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - - OAuthManager.RegisterClient _ - ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - - - - - - Registers the specified client in the application. - - The provider name. And may also contain any client name for for division into groups. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - Additional parameters to be passed to the constructor of the client class. - List of scope that will be requested from the provider. Only for OAuth 2.0. - Additional parameters that will be transferred to the provider website. - , or is null or empty. - Provider not found by . - The not suppored . - - - OAuthManager.RegisterClient - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - OAuthManager.RegisterClient - ( - "facebook" - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ); - - - OAuthManager.RegisterClient _ - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - - OAuthManager.RegisterClient _ - ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - - - You can register multiple clients to a single provider. - The following example shows how to do it. - - - var clientName = ClientName.Create("Debug", "Facebook"); - - OAuthManager.RegisterClient - ( - clientName - "000000000000000000", - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - ); - - clientName = ClientName.Create("Any name", "Facebook"); - - OAuthManager.RegisterClient - ( - clientName - "111111111111111111", - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - ); - - - Dim name As ClientName = ClientName.Create("Debug", "Facebook") - - OAuthManager.RegisterClient _ - ( - name, - "000000000000000000", - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - ) - - name As ClientName = ClientName.Create("Any name", "Facebook") - - OAuthManager.RegisterClient _ - ( - name, - "111111111111111111", - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - ) - - - - - - Checks registered provider with the specified name or not. - - The provider name or client name. - - - - Returns type of client by name. - - The provider name. - - - - Gets the list of all clients. - - - - - Gets the list of active requests. - - - - - Gets the list of registered clients. - - - - - OAuth client for Tumblr. - - -

Register and Configure a Tumblr Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Tumblr Dashboard, and Register an application. - - In the application settings you can found Consumer Key and Consumer Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new TumblrClient - ( - "2EZbsj2oF8OAouPlDWSVnESetAchImzPLV4q0IcQH7DGKECuzJ", - "4WZ3HBDwNuz5ZDZY8qyK1qA5QFHEJY7gkPK6ooYFCN4yw6crKd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New TumblrClient _ - ( - "2EZbsj2oF8OAouPlDWSVnESetAchImzPLV4q0IcQH7DGKECuzJ", - "4WZ3HBDwNuz5ZDZY8qyK1qA5QFHEJY7gkPK6ooYFCN4yw6crKd" - ) - ) - - - For more details, please visit Tumblr API Documentation. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Consumer Key obtained from the Tumblr Dashboard. - The Consumer Secret obtained from the Tumblr Dashboard. - - - - Gets an user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Tumblr. - - - - - OAuth client for SourceForge. - - -

Register a SourceForge Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Consumer ID and Consumer Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the SourceForge Authorized Applications and Register New Application. - - You can see Consumer Key and Consumer Secret, use this for creating an instance of the . - - - OAuthManager.RegisterClient - ( - new SourceForgeClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New SourceForgeClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - - - For more details, please visit Allura API. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Consumer Key obtained from the SourceForge OAuth applications. - The Consumer Secret obtained from the SourceForge OAuth applications. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - Name of the user whose data should be obtained. - - - - Gets the request token from the remote server. - - - - - Gets the access token from the remote server. - - - - - Unique provider name: SourceForge. - - - - - OAuth client for Mail.Ru. - - - Mail.Ru is a popular email service, search engine, social network, photo & video hosting, blogs and another services in Russia and CIS. -

Register and Configure a Mail.Ru Site

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Unfortunately, the interface is only in Russian. - You must have a confirmed account in Mail.Ru. - Open Sites page and click Connect a New Site. - - Create a New Site button - - Accept the terms of the agreement. - - Terms - - Enter the site name, URL and click the Next button. - - Site name and URL - - Download the receiver.html file and place it in the root directory of your site. - This step can be skipped (Пропустить). - - receiver.html file - - The last step you will find the Client ID and Client Secret. - - Use this for creating an instance of the . - - - Cleint ID and Client Secret - - - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - - - For more details, please visit to the Mail.Ru API Documentation. - -
- -

Windows Forms

- The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Add a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // mail.ru client registration - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' mail.ru client registration - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - - Result of the program is shown in the images below. - Log in with Mail.Ru - Mail.Ru User Info -

ASP .NET MVC

- The following example shows how to use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - End Sub - - The MailRuLoginResult method will handle authorization result. - - public ActionResult MailRuLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function MailRuLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Mail.Ru. - - public ActionResult MailRuLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Mail.Ru", Url.Action("MailRuLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function MailRuLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Mail.Ru", Url.Action("MailRuLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the MailRuLogin method. - - @Html.ActionLink("Log in with Mail.Ru", "MailRuLogin") - - NOTE: For proper processing, you will need to download and put on your site a receiver.html file. -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID. - The Client Secret. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - The access token must contain the user ID in the parameter x_mailru_vid. - - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Mail.Ru. - - - - - Return URL. - - - - - Implements a file to transfer in a HTTP request. - - - - - Initializes a new instance of the class. - - Content of the file. - Name of the file. - The name of the parameter. - - - - Initializes a new instance of the class. - - The name of the parameter. - The posted file. - - - - Initializes a new instance of the class. - - Content of the file. - Name of the file. - The name of the parameter. - MIME type of the file. - - - - Gets or sets the filename. - - - - - Represents authorization results. - - - - - Initializes a new instance of the class. - - - - - The ID of the authorization request. - - - - - OAuth version. For example: 1.0, 2.0. - - - - - Provider and custom client name. - - - - - Provider name. For example: facebook, twitter, google. - - - - - The access token which is used to query the provider. - - - - - The user profile details that is returned from the provider. - - - - - Gets a value indicating whether the authorization is successful. - - - - - Gets error info when the authorization is not successful. - - - - - Gets the user ID that is returned from the provider. - - - - - Gets the username that is returned from the provider. - - - - - Gets the access token value. - - - - - Represents the access token exception. - - - - - Initializes a new instance of the class with a specified message. - - The error message that explains the reason for this exception. - - - - Represents the user profile info. - - - - - Initializes a new instance of the class. - - The data source. - The mapping rules. - - - - Initializes a new instance of the class. - - The data source. - The mapping rules. - - - - Returns the or . - - - - - Gets or sets a collection containing the API request results. - - - - - Gets or sets the user ID. - - - - - Gets or sets the username. - - - - - Gets or sets the first name of the user. - - - - - Gets or sets the last name of the user. - - - - - Gets or sets the display name of the user. - - - - - Gets or sets user email address. - - - - - Gets or sets user phone. - - - - - Gets or sets user birthday. - - - - - Gets or sets user url. - - - - - Gets or sets user image url. - - - - - Gets or sets gender of the user. - - - - - Gets the first and last name. - - - - - The exception that is thrown when a user fails to login. - - - - - Initializes a new instance of the class with a specified error message. - - The error message that explains the reason for this exception. - - - - OAuth client for Yahoo. - - -

Register and Configure a Yahoo Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Consumer ID and Consumer Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open Yahoo Developer Network and Create a Project. - - In the application settings you can found Consumer Key and Consumer Secret. - Use this for creating an instance of the class. - - Note that Yahoo! does not work with the localhost. Use only a real servers. Make sure that your application on the Yahoo! dashboard configured correctly. - Yahoo! has a pretty flimsy OAuth interface. If something is done or configured incorrectly, the work will be nothing. But in general, the client is tested and works. - - OAuthManager.RegisterClient - ( - new YahooClient - ( - "dj0yJmk9Qm1vZ3p2TmtQUm4zJmQ9WVdrOU4wbGlkWGxJTkc4bWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD0xZQ--", - "a55738627652db0acfe464de2d9be13963b0ba1f" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New YahooClient _ - ( - "dj0yJmk9Qm1vZ3p2TmtQUm4zJmQ9WVdrOU4wbGlkWGxJTkc4bWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD0xZQ--", - "a55738627652db0acfe464de2d9be13963b0ba1f" - ) - ) - - - For more details, please visit Yahoo Developer Network. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Consumer Key obtained from the Yahoo Developer Dashboard. - The Consumer Secret obtained from the Yahoo Developer Dashboard. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Access token must contain the user ID in the parameter xoauth_yahoo_guid. - - - - - Gets the access token from the remote server. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - (!) - To update the access token, you must specify the return address that was used in obtaining the access token. - - - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - An exception occurs if there is no authorization code. - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - Callback address that was used in obtaining the access token. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - (!) - To update the access token, you must specify the return address that was used in obtaining the access token. - - - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - An exception occurs if there is no authorization code. - - - - Unique provider name: Yahoo. - - - - - OAuth client for VK (VKontakte). - - - VK (VKontakte) is "Russian Facebook". :-) -

Register and Configure a VKontakte Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the VK App development and click Create an Application. - - Create an Application button - - Specify the application name and type, and click the Connect Application. - - Creating an application - - Confirm by SMS. - - Confirmation - - - In the Application Settings you can found Application ID and Secure key, this is Client ID and Client Secret. - Use this for creating an instance of the class. - - NOTE: Change application status to Application ON and visible to all. - - Application settings - - - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ) - - For web projects, enable Open API, set Site address and configure Base domain in the Open API section. - - Base domains - - - For more details, please see VK App development. - -
- -

Windows Forms

- The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Insert a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // vk(ontakte) client registration - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - // application id - "4457505", - // secure secret - "wW5lFMVbsw0XwYFgCGG0" - ) - { - // display=popup - to open a popup window - Parameters = new NameValueCollection { { "display", "popup" } } - } - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' vk(ontakte) client registration - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) With _ - { - .Parameters = New NameValueCollection() From {{"display", "popup"}} - } - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("vk")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("vk")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - - Result of the program is shown in the images below. - Log in with VK(ontakte) - VK User Info -

ASP .NET MVC

- The following example shows how to use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ) - End Sub - - The VkontakteLoginResult method will handle authorization result. - - public ActionResult VkontakteLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function VkontakteLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Vkontakte. - - public ActionResult VkontakteLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("vk", Url.Action("VkontakteLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function VkontakteLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("vk", Url.Action("VkontakteLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the VkontakteLogin method. - - @Html.ActionLink("Log in with VK(ontakte)", "VkontakteLogin") - -

ASP .NET WebForms

- The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkVkontakte" runat="server" - Text="Log in with VK(ontakte)" onclick="lnkVkontakte_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkVkontakte_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("vk", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkVkontakte_Click(sender As Object, e As EventArgs) Handles lnkVkontakte.Click - OAuthWeb.RedirectToAuthorization("vk", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Application ID obtained from the VK App development. - The Secure Key obtained from the VK App development. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - - Unique provider name: VK. - - - - - Return URL. - - - - - Represents the request token results. - - - - - Initializes a new instance of the class. - - The request result. - The address of the authorization. - The query parameters. Will be used in the formation of the authorization address. - - - - Returns the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets the OAuth token. - - - - - Gets the token secret. - - - - - The parameter is used to differentiate from previous versions of the protocol. - - - - - Gets the address of the authorization. - - - - - Collection of HTTP parameters. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - The collection of parameters. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Initializes a new instance of the class. - - The body of a request. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Initializes a new instance of the class. - - The body of a request. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Initializes a new instance of the class. - - The array of parameters. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Adds a parameter to the end of the collection. - - The parameter to be added to the collection. - - - - Adds a parameter to the end of the collection. - - The name of parameter. - The parameter value. - - - - Adds a to the end of the collection. - - The name of the parameter. - The parameter value. - - - - Adds a to the end of the collection. - - The name of the parameter. - The value of the parameter. - The type of the parameter. - - - - Adds a to the end of the collection. - - The name of parameter. - The posted file. - - - - Adds a to the end of the collection. - - The posted file. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The Content-Type of the file. - The content of the file. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The content of the file. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The Content-Type of the file. - The file stream. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The file stream. - - - - Adds a to the end of the collection. - - The content of the request. - - - - Adds a to the end of the collection. - - The content of the request. - - - - Adds a to the end of the collection. - - The content of the request. - - - - Adds the items of the specified collection to the end of the current instance of the . - - The collection whose items should be added to the end of the current instance of the . - - - - Adds a to the end of the collection. - - The name of parameter. - The parameter value. - - - - Adds a to the end of the collection. - - The name of parameter. - The parameter value. - - - - Adds file as content to the end of the collection. - - The posted file. - - - - Adds content to the end of the collection. - - The Content-Type of the . - The content value. - - - - Inserts an element into the instance of the at the specified index. - - The zero-based index at which item should be inserted. - The to insert. - - - - Inserts the elements of a collection into the instance of the at the specified index. - - The zero-based index at which the new elements should be inserted. - The collection whose elements should be inserted into the instance of the . - - - - Removes the first occurrence of a specific parameter from the . - - The parameter to remove from the . - - true if is successfully removed; otherwise, false. - This method also returns false if was not found in the . - - - - - Removes all the elements that match the conditions defined by the specified predicate. - - The delegate that defines the conditions of the elements to remove. - The number of elements removed from the . - - - - Removes the element at the specified index of the . - - The zero-based index of the element to remove. - - - - Removes a range of elements from the . - - The zero-based starting index of the range of elements to remove. - The number of elements to remove. - - - - Removes all elements from the . - - - - - Updates status of the collection. - - - - - Checks parameters types. - - The type for checking. - - - - Returns a string query parameters encoded by default method (). - - - - - Returns a string of query parameters with a specified separator. - - The separator of query parameters. For example: & - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified separator and encoding parameters. - - The separator of query parameters. - The type of the encoder. - The types of parameters to be used. - - - - Copies elements of the to a new instance. - - The true value included into the results only the parameters. The default value is false - all parameters. - - - - Gets a body for the request. - - - - - Writes the parameters to the request. - - The instance of the request. - - - - Writes a file to the request. - - The name of the parameter. - The filename. - The Content-Type of the file. - The content of the file. - The output stream instance. - - - - Writes a form-data parameter to the request. - - The name of the parameter. - The value of the parameter. - The output stream instance. - - - - Writes any parameter to the request. - - The Content-Type of the . - The content value. - The instance of the output stream. - - - - The assignment operator for array of the . - - The array that will be used as the . - New instance of the . - - - - The assignment operator for the . - - The collection that will be used as the . - New instance of the . - - - - The assignment operator for the byte array. - - The byte array of the request body. - New instance of the . - - - - The assignment operator for the . - - The instance of the of the request body. - New instance of the . - - - - Gets a value indicating whether the current collection has a files. - - - - - Gets a value indicating whether the current collection has a . - - - - - Gets a boundary for a request. - - - - - Gets or sets code page for parameters encoding. - - - - - The exception that is thrown when adding a to the and collection has one a . - - - - - Initializes a new instance of the . - - - - - OAuth client for Assembla. - - -

Register and Configure an Assembla Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - - Register a new OAuth application. - - In the application settings you can found Application ID and Application Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new AssemblaClient - ( - "bOS4QkXnmr5jhdacwqjQXA", - "701ee6dedf74fc4ad75bfa7476666a2f" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New AssemblaClient _ - ( - "bOS4QkXnmr5jhdacwqjQXA", - "701ee6dedf74fc4ad75bfa7476666a2f" - ) - ) - - - For more details, please visit Assembla API Documentation Site. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Application ID obtained from the Assembla Applications Manager. - The Application Secret obtained from the Assembla Applications Manager. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Assembla. - - - - - The for . - - - - - Initializes a new instance of the class. - - - - - Returns a collection of property descriptors for the object represented by this type descriptor. - - - - - The properties collection. - - - - - Implements a request body. - - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Represents a method that is called for parsing item of the API data. - - The instance to parse. - - - - References a method to be called when a corresponding asynchronous web request completes. - - The result of the asynchronous web request. - - - - Represents data mapping item for API results. - - - - - Initializes a new instance of the class. - - - - - Gets or sets the key name in the data source. - - - - - Gets or set the property name in the destination object. - - - - - Gets or sets the data type of the property in the destination object. - - - - - Gets or sets the data format. - - - - - Gets or sets a custom parser of the data. - - - - - Represents the request item to OAuth server. - - - - - Initializes a new instance of the class. - - The instance of the OAuth client. - The client name. - - - - Gets name of the client. - - - - - Gets instance of the OAuth client. - - - - - Gets date and time creation of the request. - - - - - Represents a HTTP authorization header. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with specific authorization type and value. - - - - - Initializes a new instance of the class from specific source. - - - - - Removes the value with the specified key from the . - - The key of the element to remove. - - true if the element is successfully found and removed; otherwise, false. - This method returns false if key is not found in the or is not collection. - - - - - Returns OAuth string of the current object for Authorization header. - - - - - Invoked before sending a web request. - - HTTP Method of the request: POST, PUT, GET or DELETE. - URL of the web request. - The value of the Content-Type HTTP header. - >Parameters of the web request. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Gets or sets authorization method. - - - - - Gets or sets parameters of the authorization. - - - - - Authorization parameters. - - - - - Sorted authorization parameters. - - - - - Gets or sets the value associated with the specified key. - - The key of the value to get or set. - - - - The list of access token types. - - - - - Bearer - - - - - OAuth - - - - - Represents the name of the client. - - - - - Initializes a new instance of the . - - The provider name. - - - - Initializes a new instance of the . - - The client name. Any string. - The provider name. - - - - Returns a new instance with a specified . - - - - - Returns a new instance with a specified and . - - - - - Converts a specified string to . - - The string to parse. - - - - Encodes a string. - - The string to encode. - - - - Decodes a string. - - The string to decode. - - - - Escapes a special characters in a string. - - The string to escape. - - - - Converts any escaped characters in the input string. - - The input string containing the value to convert. - - - - Returns a string that represents the current . - - - - - Determines whether two object instances are equal. - - The object to compare with the current instance of the . - true if the specified object is equal to the current ; otherwise, false. - - - - Determines whether two object instances are equal. - - The instance of to compare with the current instance of the . - true if the specified instance is equal to the current ; otherwise, false. - - - - Serves as a hash function for a particular type. - - A hash code for the current . - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Indicate whether two are not equal. - - The first instance. - The second instance. - - - - Indicate whether two are equal. - - The first instance. - The second instance. - - - - Gets the client name. - - - - - Gets the provider name. - - - - - Gets a md5 hash code for the current instance of the . - - - - - Represents the collection of the . - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the with a specified reference to parent. - - - - - Initializes a new instance of the by other an instance of the . - - - - - Adds the specified key and value to the collection. - - The key of the element to add. - The value of the element to add. - - - - Determines whether the collection contains the specified key. - - The key to locate in the collection. - is null. - - - - Removes the value with the specified key from the collection. - - The key of the element to remove. - - true if the element is successfully found and removed; otherwise, false. - - - - - Returns a string that represents the current . - - - - - Determines whether two object instances are equal. - - The object to compare with the current instance of the . - true if the specified object is equal to the current ; otherwise, false. - - - - Returns a string that represents the specified item of the . - - The item to converted. - - - - Returns a string that represents the specified instance. - - The value to converted. - - - - Adds the specified item to the . - - The item to add. - - - - Removes all items from the collection. - - - - - Determines whether the collection contains a specific value. - - The object to locate in the collection. - - - - Removes the first occurrence of a specific object from the collection. - - The object to remove from the collection. - - - - Gets the value associated with the specified key. - - The key whose value to get. - When this method returns, the value associated with the specified key, if the key is found; otherwise, the . - - - - [Is not implemented] Copies the elements of the collection to an , starting at a particular index. - - The one-dimensional that is the destination of the elements copied from collection. The must have zero-based indexing. - The zero-based index in array at which copying begins. - - - - Returns an enumerator that iterates through a collection. - - - - - Returns an enumerator that iterates through a collection. - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Returns instance from . - - The value from which will be returned the . - - - - Gets or sets items of the collection. - - - - - The reference to parent. - - - - - Gets or sets the value associated with the specified key. - - The key of the value to get or set. - - - - Gets or sets the element at the specified index. - - The zero-based index of the element to get or set. - - - - Gets a collection containing the keys in the collection. - - - - - Gets a collection containing the values in the collection. - - - - - Gets the number of elements contained in the collection. - - - - - Gets a collection containing the keys in the collection. - - - - - Gets a collection containing the values in the collection. - - - - - Gets a value indicating whether the collection is read-only. Always false. - - - - - Represents property description of a class. - - - - - The data reader. - - - - - Initializes a new instance of the class. - - - - - Returns whether resetting an object changes its value. - - The component to test for reset capability. - - - - Gets the current value of the property on a component. - - The component with the property for which to retrieve the value. - - - - Resets the value for this property of the component to the default value. - - The component with the property value that is to be reset to the default value. - - - - Sets the value of the component to a different value. - - The component with the property value that is to be set. - The new value. - - - - Determines a value indicating whether the value of this property needs to be persisted. - - The component with the property to be examined for persistence. - - - - Gets a value indicating whether this property is read-only. - - - - - Gets the type of the property. - - - - - Gets the type of the component this property is bound to. - - - - - Represents helper class for sessions management of OAuth. - - - Mainly the class is intended for web projects. - But you can use some methods of the class in desktop applications together with the WebBrowser control. - - The methods , - , - and - - will not work in desktop applications. - - - -

ASP .NET WebForms

- The following example shows how to use the in ASP .NET WebForms. - To redirect the user to the login page is used the method. - Processing of the authorization results is performed by . - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkTwitter" runat="server" - Text="Log in with Twitter" onclick="lnkTwitter_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkTwitter_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Twitter", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkTwitter_Click(sender As Object, e As EventArgs) Handles lnkTwitter.Click - OAuthWeb.RedirectToAuthorization("Twitter", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - -

Windows Forms

- The following example shows how to use the in desktop applications. - Methods redirection in Windows Forms applications do not work. To get the address of the authorization is used. - To test the example, create a new Windows Forms project with two forms. Add a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // mail.ru client registration - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' mail.ru client registration - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - -
-
- - - Redirects current client to the authorization page of the specified provider. - - Provider name, through which it is necessary to authorize the current user. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider with specified parameters. - - Provider name, through which it is necessary to authorize the current user. - Additional parameters to be passed to the authorization query. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider, query parameters and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - Additional parameters to be passed to the authorization query. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider, query parameters and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - Additional parameters to be passed to the authorization query. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Returns the authorization URL of the specified provider. - - Provider name, through which it is necessary to authorize the current user. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider with specified parameters. - - Provider name, through which it is necessary to authorize the current user. - Additional parameters to be passed to the authorization URL. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider, query parameters and return URL. - - Provider name, through which it is necessary to authorize the current user. - Additional parameters to be passed to the authorization URL. - The address to which the user is redirected after the authorization. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider, query parameters and return URL. - - - The provider name, through which it is necessary to authorize the current user; or the name of the registered client. - - Additional parameters to be passed to the authorization URL. - The address to which the user is redirected after the authorization. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Verifies the authorization results for the current URL. - - - The method will not work in desktop applications. For desktop applications you can use the overloads or . - - - Returns the verification results. - - - - - Verifies the authorization results for the specified URL. - - Address at which to perform the verification. - - Returns the verification results. - - - - - Verifies the authorization results for the specified request identifier and the code of the authorization. - - Request identifier. - The authorization code received from the provider server. - - Returns the verification results. - - - This method is intended for internal use. It is recommended to use the overload or . - - - - - Verifies the authorization results for the current URL and removes the request from memory. - - - The method will not work in desktop applications. For desktop applications you can use the overloads or . - - - Returns the verification results. - - - - - Verifies the authorization results for the specified URL, and removes the request from memory. - - Address at which to perform the verification. - - Returns the verification results. - - - - - Verifies the authorization results for the specified request identifier and the code of the authorization, and removes the request from memory. - - Request identifier. - The authorization code received from the provider server. - - Returns the verification results. - - - This method is intended for internal use. It is recommended to use the overload or . - - - - - OAuth client for Odnoklassniki. - - - Odnoklassniki is a social network service for classmates and old friends. It is popular in Russia and CIS. -

Register and Configure a Odnoklassniki Site

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open My Games page and click My Uploaded Games. - - My Games in the footer menu - - - My Uploaded Games - - Click Add App. - - Add App button - - Enter the Title, Shortname, Description, Image link and App link. Select Application type (External type) and Permission. - - - (!) - - It is important to provide a link to the application (App link).
- You must use this link as the return URL. Even for desktop applications.
- You can use localhost for desktop applications.
- It is important to specify the type of application: External. -
-
-
- - App form - - In your email box you will find email message with the Client ID, Client Secret and Public key. - - Email message - - - Use this for creating an instance of the . - - - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ) - - - For more details, please visit to the Odnoklassniki API Documentation. - -
- -

Windows Forms

- The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Add a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // odnoklassniki client registration - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - // application ID - "1094959360", - // sectet key - "E45991423E8C5AE249B44E84", - // public key - "CBACMEECEBABABABA" - ) { ReturnUrl = "http://localhost" } // return url - it's important - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' odnoklassniki client registration - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) With { .ReturnUrl = "http://localhost" } - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Odnoklassniki")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Odnoklassniki")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - -

ASP .NET MVC

- The following example shows how to use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - // application ID - "1094959360", - // sectet key - "E45991423E8C5AE249B44E84", - // public key - "CBACMEECEBABABABA" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ) - End Sub - - The OdnoklassnikiLoginResult method will handle authorization result. - - public ActionResult OdnoklassnikiLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function OdnoklassnikiLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Odnoklassniki. - - public ActionResult OdnoklassnikiLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Odnoklassniki", Url.Action("OdnoklassnikiLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function OdnoklassnikiLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Odnoklassniki", Url.Action("OdnoklassnikiLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the OdnoklassnikiLogin method. - - @Html.ActionLink("Log in with Odnoklassniki", "OdnoklassnikiLogin") - -

ASP .NET WebForms

- The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - // application ID - "1094959360", - // sectet key - "E45991423E8C5AE249B44E84", - // public key - "CBACMEECEBABABABA" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - Response.Write(String.Format("Email: {0}", user.Email)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Response.Write(String.Format("Email: {0}", user.Email)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkOdnoklassniki" runat="server" - Text="Log in with Odnoklassniki" onclick="lnkOdnoklassniki_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkOdnoklassniki_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Odnoklassniki", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkOdnoklassniki_Click(sender As Object, e As EventArgs) Handles lnkOdnoklassniki.Click - OAuthWeb.RedirectToAuthorization("Odnoklassniki", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID. - The Client Secret. - The Public Key. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - - Unique provider name: Odnoklassniki. - - - - - Public Key for access to API. - - - - - The list of the types a HTTP parameters. - - - - - Unformed parameter. - - - - - Parameter of the query string. - - - - - Parameter of the form. - - - - - File. - - - - - Body of the request. - - - - - OAuth client for Instagram. - - -

Register and Configure a Instagram Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Register as Developer and Register new Client ID. - - In the application settings you can found Client ID and Client Key. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new InstagramClient - ( - "215a1941ebed4e4fa74e94dd84762836", - "ba53a710e1624870bc066e7a9ae38601" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New InstagramClient _ - ( - "215a1941ebed4e4fa74e94dd84762836", - "ba53a710e1624870bc066e7a9ae38601" - ) - ) - - - For more details, please visit Instagram Developer Documentation. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the Instagram Manage Clients. - The Client Secret obtained from the Instagram Manage Clients. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Instagram. - - - - - OAuth client for Yandex. - - - Yandex is a popular search engine in Russia and CIS. -

Register and Configure a Yandex Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the register new application page, fill out the form and click Save. - NOTE: Russian language is available on the yandex.ru - Specify the application name and set permissions. - - To access a users profile, select Yandex.Username: Date of birth; Email address; User name, surname and gender. - This minimum permissions that are required to work. - - For web project, set a Callback URI. - NOTE: For desktop applications set Callback URI to https://oauth.yandex.ru/verification_code. - - Register new application - - - In the next step you will see an Application ID and Application password, this is Client ID and Client Secret. - Use this for creating an instance of the . - - - Client ID and Client Secret - - - OAuthManager.RegisterClient - ( - new YandexClient - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New YandexClient _ - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ) - - - For more details, please visit Yandex OAuth Documentation. - -
- -

Console Applications

- The following example shows how to use the in Console Applications. - For desktop applications, the user will need to manually enter authorization code. - - class Program - { - static void Main(string[] args) - { - try - { - var yandex = new YandexClient - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ); - - // open the login page in browser - System.Diagnostics.Process.Start(yandex.AuthorizationUrl); - - // waiting of entering the access code - string code = ""; - while (String.IsNullOrEmpty(code)) - { - Console.WriteLine("Enter access code:"); - code = Console.ReadLine(); - } - - Console.WriteLine(); - - // set authorization code - yandex.AuthorizationCode = code; - // get user info - var user = yandex.GetUserInfo(); - Console.WriteLine("User ID: {0}", user.UserId); - Console.WriteLine("E-Mail: {0}", user.Email); - Console.WriteLine("Name: {0}", user.DisplayName); - Console.WriteLine("Birthday: {0}", user.Birthday); - Console.WriteLine("Sex: {0}", user.Sex); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - Console.ReadKey(); - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Module Module1 - - Sub Main() - Try - Dim yandex As New YandexClient _ - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ' open the login page in browser - System.Diagnostics.Process.Start(yandex.AuthorizationUrl) - - ' waiting of entering the access code - Dim code As String = "" - Do While String.IsNullOrEmpty(code) - Console.WriteLine("Enter access code:") - code = Console.ReadLine() - Loop - - ' set authorization code - yandex.AuthorizationCode = code - - ' get user info - Dim user As UserInfo = yandex.GetUserInfo() - Console.WriteLine("User ID: {0}", user.UserId) - Console.WriteLine("E-Mail: {0}", user.Email) - Console.WriteLine("Name: {0}", user.DisplayName) - Console.WriteLine("Birthday: {0}", user.Birthday) - Console.WriteLine("Sex: {0}", user.Sex) - Catch ex As Exception - Console.WriteLine(ex.Message) - End Try - Console.ReadKey() - End Sub - - End Module - - Result of the program is shown in the images below. - Log in with Yandex - Access code - User info -

ASP .NET WebForms

- In a web projects you can use the and . - The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new YandexClient - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New YandexClient _ - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("E-Mail: {0}<br />", user.Email)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("E-Mail: {0}<br />", user.Email)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkYandex" runat="server" - Text="Log in with Yandex" onclick="lnkYandex_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkYandex_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Yandex", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkYandex_Click(sender As Object, e As EventArgs) Handles lnkYandex.Click - OAuthWeb.RedirectToAuthorization("Yandex", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - - NOTE: Do not forget to adjust the Callback URI in the Yandex Application Settings. -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Application ID. - The Application Password. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Unique provider name: Yandex. - - - - - Return URL. - - - - - Represents authorization parameters for OAuth 1.0. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with specific value. - - - - - Updates the nonce and the timestamp. - - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The query parameters. - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The query parameters. - - - - Gets or sets the consumer key. - - - - - Gets or sets the consumer secret. - - - - - Gets or sets the token. - - - - - Gets or sets the secret token. - - - - - Gets or sets the signature method. - - - - - Gets or sets the nonce. - - - - - Gets or sets the timestamp. - - - - - Gets or sets the version of the OAuth. - - - - - Gets or sets the signature. - - - - - Gets or sets the callback address. - - - - - Gets or sets the verifier code. - - - - - Represents the authorization grant type. - - - - - Using an authorization code to confirm the identity (grant type is authorization_code). - - - - - Using username and password (grant type is password). - - - - - Using basic authorization with username and password (grant type is client_credentials). - - - - - Using a token to refreshing the access token (grant type is refresh_token). - - - - - Initializes a new instance with a specified . - - The value of grant type. - - - - Returns a string that represents the current . - - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Gets or sets the value. - - - - - Gets a value indicating whether the current value is authorization_code or not. - - - - - Gets a value indicating whether the current value is password or not. - - - - - Gets a value indicating whether the current value is client_credentials or not. - - - - - The exception that is thrown when has more than one . - - - - - Initializes a new instance of the . - - - - - The exception that is thrown when a resource owner or authorization server denied the request. - - - - - Initializes a new instance of the class with a specified error message and the exception that is the cause of this exception. - - The error message that explains the reason for this exception. - - - - Represents the error results of the query. - - - - - Initializes a new instance of the class. - - The request results. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets a value indicating whether the current request result is successful or not. - - Always has the value false. - - - - OAuth client for Facebook. - - -

Register and Configure a Facebook Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - You need to register as developer. - - Open the Facebook Developers and Create a New App. - - Create new application menu - - Specify the application name and click the Create App. - - Create new application form - - - In the application dashboard you can found App ID and App Secret, this is Client ID and Client Secret. - Use this for creating an instance of the class. - - - App ID and App Secret - - - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - You can use the App ID and App Secret for desktop, mobile and web projects. -

The application availability

- - To manage the status of the application, you must provide contact information. - - - Enter a contact email on the Settings page. - - - Contact Email - - - And now, you can change availability status of the application on the Status & Review page. - - - Make App Public - -

Configure application for web projects

- For web projects, configure return URLs. - - Open the application Settings and click Advanced tab. - - - Advanced tab - - - You must add the return URLs to the Valid OAuth redirect URIs field of the Security section. - - Do not forget to save your changes. - NOTE: If the application will be used for web and desktop, then also add URL: https://www.facebook.com/connect/login_success.html. - NOTE: Enable Client OAuth Login if it's disabled. - - Valid OAuth redirect URIs - - - For more details, please see Facebook Developer Documentation. - -
- - The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Insert a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // facebook client registration - OAuthManager.RegisterClient - ( - new FacebookClient - ( - // app id - "1435890426686808", - // app secret - "c6057dfae399beee9e8dc46a4182e8fd" - ) - { - // display=popup - to open a popup window - Parameters = new NameValueCollection { { "display", "popup" } } - } - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' facebook client registration - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) With _ - { - .Parameters = New NameValueCollection() From {{"display", "popup"}} - } - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Insert a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("facebook")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("facebook")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - - Result of the program is shown in the images below. - Log in with Facebook - Facebook User Info - - - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The App ID obtained from the Facebook Developers. - The App Secret obtained from the Facebook Developers. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - For more details, please see User method in Guide of Facebook Graph API. - - - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Unique provider name: Facebook. - - - - - Return URL. - - - - - OAuth client for GitHub. - - -

Register and Configure a GitHub Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - - Register a new OAuth application. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new GitHubClient - ( - "e14122695d88f5c95bce", - "cde23ec001c5180e01e865f4efb57cb0bc848c16" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New GitHubClient _ - ( - "e14122695d88f5c95bce", - "cde23ec001c5180e01e865f4efb57cb0bc848c16" - ) - ) - - - For more details, please see GitHub Development Guides. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the GitHub Applications. - The Client Secret obtained from the GitHub Applications. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: GitHub. - - - - - Provides helpers methods for OAuth. - - - - - Unreserved characters for the method. - - - http://tools.ietf.org/html/rfc3986#page-13 - - - - - This is main helper class. - - - - - Percent encoding. - - The text to encode. - The object that specifies the encoding scheme. - - For more details, please see: - - - - - - - - - Percent encoding. - - The text to encode. - - - - Encodes a URL string using the specified encoding object. - - The text to encode. - The type of the encoder. - - - - Encodes a URL string using the specified encoding object. - - The text to encode. - The object that specifies the encoding scheme. - The type of the encoder. - - - - Encodes a string into JavaScript string. - - The string to encode. - - - - Generate timestamp for a signature (only for OAuth 1.0). - - - - The timestamp value MUST be a positive integer. Unless otherwise - specified by the server's documentation, the timestamp is expressed - in the number of seconds since January 1, 1970 00:00:00 GMT. - - For more details, please see: - - - - - Generate random key. - - - - - Compute MD5 hash. - - Value that must be processed. - - - - Converts the string value to its equivalent string representation that is encoded with base-64 digits. - - A composite format string for encoding to Base64. - An object array that contains zero or more objects to format. - The string representation, in base 64. - - - - Performs a request using a GET method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request using a POST method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for web request. - The value of the Content-Type HTTP header. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request using a PUT method. - - URL to which will be sent to the request. - Parameters to be passed to the request. - Authorization header value. - HTTP headers for the request. - The value of the Content-Type HTTP header. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request using a DELETE method. - - URL to which will be sent to the request. - Parameters to be passed to the request. - Authorization header value. - HTTP headers for the request. - Access token to be used in the request. - Returns an instance of the class, which contains the result of the request. - - Can not be used simultaneously and . Use only one of these parameters. - - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request. - - HTTP Method: POST (default), PUT, GET or DELETE. - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for web request. - The value of the Content-Type HTTP header. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Reads results of the web request to the string. - - instance. - - - - Performs an async request using a GET method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request using a POST method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - The value of the Content-Type HTTP header. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request using a PUT method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - The value of the Content-Type HTTP header. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request using a DELETE method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request. - - HTTP Method: POST (default), PUT, GET or DELETE. - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - The value of the Content-Type HTTP header. - A delegate that, if provided, is called when an async web request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Gets the value of the specified , if the is a . - - Source of data. - The key is to be obtained. - - - - Returns a string containing a number. - - The value for processing. - - - - Gets signature for the current request. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - The authorization parameters. - - - - Gets signature for the current request. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - The authorization parameters. - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Very sexy list. - - - - - No sex. - - :o) - - - - Male. - - - - - Female. - - - - - Programmer. - - - - - Deep Thought. - - - - - The list of authorization type. - - - - - Basic - - - - - Bearer - - - - - Digest - - - - - OAuth - - - - - OAuth client for Foursquare. - - -

Register and Configure a Foursquare Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Foursquare App and Create app. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new FoursquareClient - ( - "LHYZN1KUXN50L141QCQFNNVOYBGUE3G3FCWFZ3EEZTOZHY5Q", - "HWXYFLLSS2IUQ0H4XNCDAZEFZKIU3MZRP5G55TNBDHRPNOQT" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New FoursquareClient _ - ( - "LHYZN1KUXN50L141QCQFNNVOYBGUE3G3FCWFZ3EEZTOZHY5Q", - "HWXYFLLSS2IUQ0H4XNCDAZEFZKIU3MZRP5G55TNBDHRPNOQT" - ) - ) - - - For more details, please visit Foursquare for Developers. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the Foursquare Apps. - The Client Secret obtained from the Foursquare Apps. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Foursquare. - - -
-
diff --git a/bin/net40/Nemiro.OAuth.dll b/bin/net40/Nemiro.OAuth.dll deleted file mode 100644 index d1cc9fbb87034413b719e630eb8b5577f7fe587e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126976 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

K%alErs|d6%ijaMBdVFH$$?@an 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 diff --git a/bin/net45/Nemiro.OAuth.XML b/bin/net45/Nemiro.OAuth.XML deleted file mode 100644 index 9285d26..0000000 --- a/bin/net45/Nemiro.OAuth.XML +++ /dev/null @@ -1,9540 +0,0 @@ - - - - Nemiro.OAuth - - - -

- Represents base properties and method for access token results. - - - - - Represents the base class for results of remote requests. - - - - - The universal type that represents a value. - - - represents any type of data. - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the with a specified value. - - The value. - - - - Initializes a new instance of the with a specified value and attributes. - - The value. - The collection of an attributes. - - - - Initializes a new instance of the with a specified value and reference to parent. - - The value. - The instance of the . - - - - Initializes a new instance of the with a specified value, attributes and reference to parent. - - The value. - The collection of an attributes. - The instance of the . - - - - Copies items of the to a new Dictionary<string, object>. - - - A Dictionary<string, object> containing copies of the elements of the . - A null value, if the property is false or the is empty. - - - - - Copies items of the to a new . - - - A containing copies of the elements of the . - A null value, if the property is false or the is empty. - - - - - Returns a array that represents the current . - - - A array containing the current . - A null value, if the property and is false or the is empty. - - - - - Determines whether the contains the specified key. - - The key to locate in the . - true if the is not null and contains an element with the specified ; otherwise, false. - is null. - - - - Determines whether the contains the specified key. - - The key to locate in the . - true if the is not null and contains an element with the specified ; otherwise, false. - - - - Adds the specified key and value to the . - - The key of the element to add. - The value of the element to add. - - Returns the added element. - - - - If the current is not a collection ( is false), it will automatically be converted to the collection. - If the current is not empty, then it will be assigned a key ____ in a new collection. - - - - - - Adds the specified key and value to the . - - The key of the element to add. - The value of the element to add. - The reference to parent of the elemet to add. - - Returns the added element. - - - - If the current is not a collection ( is false), it will automatically be converted to the collection. - If the current is not empty, then it will be assigned a key ____ in a new collection. - - - - - - Removes the value with the specified key from the . - - The key of the element to remove. - - true if the element is successfully found and removed; otherwise, false. - This method returns false if key is not found in the or is not collection ( is false). - - - - - Parses the and converts to . - - The reference to the collection, which will be placed the result of parsing . - The for parsing. - The reference to parent. - - - - Returns the of the specified attribute. - - The name of the attribute whose value you want to get. - - - - Returns parent for new instance of . - - - - - Initializes a new instance. - - - - - Initializes a new instance with a specified . - - The value. - - - - Initializes a new instance with a specified and . - - The value. - The collection of an attributes. - - - - Initializes a new instance with a specified and reference to . - - The value. - The instance of the . - - - - Initializes a new instance with a specified , and reference to . - - The value. - The instance of the . - The collection of an attributes. - - - - Initializes an empty instance with a specified and reference to . - - The collection of an attributes. - The instance of the . - - - - Converts the specified JSON string to an . - - A string containing a JSON data to parse. - A new instance. - is null. - The length exceeds the value of . - The recursion limit defined by was exceeded. - contains an unexpected character sequence. - is a dictionary type and a non-string key value was encountered. - includes member definitions that are not available on the target type. - It is not possible to convert to the target type. - - - - Converts the specified XML string to an . - - A string containing a XML data to parse. - A new instance. - is null. - - - - Converts the specified parameters string to an . - - A string containing an url parameters to parse. - A new instance. - contains an CR or LF characters. - - If is null or empty, the function returns an instance. - - - - - Converts the specified JSON string to an . A return value indicates whether the conversion succeeded. - - A string containing a JSON data to parse. - If successful, this parameter takes the result of parsing data. - true if s was converted successfully; otherwise, false. - - - - Converts the specified XML string to an . A return value indicates whether the conversion succeeded. - - A string containing a XML data to parse. - If successful, this parameter takes the result of parsing data. - true if s was converted successfully; otherwise, false. - - - - Converts the specified url parameters string to an . A return value indicates whether the conversion succeeded. - - A string containing an url parameters to parse. - If successful, this parameter takes the result of parsing data. - true if s was converted successfully; otherwise, false. - - - - Indicates whether the specified value is null or an . - - The instance to test. - true if the parameter is null or is false; otherwise, false. - - - - Gets the underlying type code of the . - - - - - - Converts the value of this instance to an equivalent value using the specified culture-specific formatting information. - - An object that supplies culture-specific formatting information. - A value equivalent to the value of this instance. - - - - - - Converts the value this instance to an equivalent 8-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 8-bit unsigned integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent Unicode character using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A Unicode character equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A instance equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent number using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A number equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent double-precision floating-point number using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A double-precision floating-point number equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 16-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 16-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 32-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 32-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 64-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 64-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 8-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 8-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent single-precision floating-point number using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A single-precision floating-point number equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A instance equivalent to the value of this instance. - - - - Converts the value of this instance to an of the specified that has an equivalent value, using the specified culture-specific formatting information. - - The to which the value of this instance is converted. - An interface implementation that supplies culture-specific formatting information. - An instance of type whose value is equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 16-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 16-bit unsigned integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 32-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 32-bit unsigned integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 64-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 64-bit unsigned integer equivalent to the value of this instance. - - - - Creates a new object that is a copy of the current instance. - - A new object that is a copy of this instance. - - - - Returns an enumerator that iterates through a collection. - - An object that can be used to iterate through the collection. - - - - Returns an enumerator that iterates through a collection. - - An System.Collections.IEnumerator<UniValue> object that can be used to iterate through the collection. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Serves as a hash function for a particular type. - - A hash code for the current . - - - - Returns a string that represents the current . - - - - - Determines whether two object instances are equal. - - The object to compare with the current instance of the . - true if the specified object is equal to the current ; otherwise, false. - - - - Determines whether two instances are equal. - - The to compare with the current instance of the . - true if the specified is equal to the current ; otherwise, false. - - - - Determines whether this instance and another specified object have the same value. - - The string to compare to this instance of the . - true if the value of the parameter is the same as this instance; otherwise, false. - - - - Determines whether this string and a specified object have the same value. A parameter specifies the culture, case, and sort rules used in the comparison. - - The string to compare to this instance. - One of the enumeration values that specifies how the strings will be compared. - true if the value of the parameter is the same as this instance; otherwise, false. - - - - Converts the as a . - - The instance. - - - - Converts the as a Dictionary<string, object>. - - The instance. - - - - Converts the as an array. - - The instance. - - - - Converts the as an array. - - The instance. - - - - Converts the as a array. - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from Dictionary<string, object>. - - The value from which will be created a new instance of the . - - - - Creates a new instance from array. - - The value from which will be created a new instance of the . - - - - Creates a new instance from array. - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Indicate whether two are not equal. - - The first instance. - The second instance. - - - - Indicate whether two are equal. - - The first instance. - The second instance. - - - - Indicate whether and are not equal. - - The instance. - The string. - - - - Indicate whether and are equal. - - The instance. - The string. - - - - Returns an that can be bound to a data source from an object that does not implement an itself. - - - - - Returns a collection of custom attributes for this instance of a component. - - - - - Returns the class name of this instance of a component. - - - - - Returns the name of this instance of a component. - - - - - Returns a type converter for this instance of a component. - - - - - Returns the default event for this instance of a component. - - - - - Returns the default property for this instance of a component. - - - - - Returns an editor of the specified type for this instance of a component. - - A that represents the editor for this object. - - - - Returns the events for this instance of a component using the specified attribute array as a filter. - - An array of type that is used as a filter. - - - - Returns the events for this instance of a component. - - - - - Returns the properties for this instance of a component using the attribute array as a filter. - - An array of type that is used as a filter. - - - - Returns the properties for this instance of a component. - - - - - Returns an object that contains the property described by the specified property descriptor. - - A that represents the property whose owner is to be found. - - - - Gets or sets the value. - - - - - Gets a collection of string keys and values of the current . - - - Has a null value, if the property is false. - - - - - Gets or sets an attributes of the XML item (only for XML). - - - - - Gets the value associated with the specified key of the . - - The key of the value to get. - - - - Gets the value associated with the specified index of the . - - The index of the value to get. - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to array. - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to numeric type. - - - - - Gets a value indicating whether the current object has a value. - - - - - Gets a value indicating whether the current object has an attributes (only for xml data type). - - - - - Gets the number of elements actually contained in the . - - - - - Gets or sets the key for the current item, if the current item included into the collection. - - - Assigned automatically when parsing data of JSON, XML or query string. - root for root elements. - value for . - ____ for new collections created by the developer manually. - - - - - The parent of the current item, if the current item included into the collection. - - - - - Gets or sets a value that indicates whether the data type of the is array. - - - This affects the representation of the object as a string. For arrays in a JSON is not use the . - - - - - Gets or sets a value that indicates whether the type is unreferenced. - - - - - Represents the empty . - - - - - Gets a value indicating whether the collection is a collection of objects. - - - - - Initializes a new instance of the class. - - The request results. - - - - Initializes a new instance of the class. - - The content type of the response. - The source of the response. - - - - Initializes a new instance of the class. - - The content type of the response. - The source of the response. - The HTTP headers of the response. - The HTTP status code of the response. - - - - Parses the source to the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets or sets the HTTP status code of the output returned to the client. - - - - - Gets a value indicating whether the current request result is successful or not. - - - Successful result - is a response code from 200 to 299. - - - - - Gets or sets the content type of the response. - - - - - Gets or sets the http headers of the response. - - - - - Gets the Content-Disposition header of the response. - - - - - Gets the file name, if is file. - - - - - Gets or sets the source of the response. - - - - - Gets a value indicating the is file or not. - - - - - Gets a value indicating whether the is empty or not. - - - - - Gets or sets the processed result of the response. - - - - - Gets a value indicating the is or not. - - - - - Gets a value indicating the is or not. - - - - - Gets a value indicating the is XML or not. - - - - - Gets a value indicating the is array or not. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - Result of request to the OAuth server. - - - - Returns the . - - - - - Converts the specified string to an . - - A string containing an access token to parse. - A new instance. - - - - Converts the specified string to an . - - Type Inherited from the that should be returned. - A string containing an access token to parse. - A new instance. - - - - Indicates whether the specified value is null or an . - - The instance to test. - true if the parameter is null or is false; otherwise, false. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - The access token issued by the authorization server. - - - - - Represents the empty . - - - - - Gets a value indicating whether the is empty or not. - - - - - Represents authorization results. - - - - - Initializes a new instance of the class. - - - - - The ID of the authorization request. - - - - - OAuth version. For example: 1.0, 2.0. - - - - - Provider and custom client name. - - - - - Provider name. For example: facebook, twitter, google. - - - - - The access token which is used to query the provider. - - - - - The user profile details that is returned from the provider. - - - - - Gets a value indicating whether the authorization is successful. - - - - - Gets error info when the authorization is not successful. - - - - - Gets the user ID that is returned from the provider. - - - - - Gets the username that is returned from the provider. - - - - - Gets the access token value. - - - - - Represents the name of the client. - - - - - Initializes a new instance of the . - - The provider name. - - - - Initializes a new instance of the . - - The client name. Any string. - The provider name. - - - - Returns a new instance with a specified . - - - - - Returns a new instance with a specified and . - - - - - Converts a specified string to . - - The string to parse. - - - - Encodes a string. - - The string to encode. - - - - Decodes a string. - - The string to decode. - - - - Escapes a special characters in a string. - - The string to escape. - - - - Converts any escaped characters in the input string. - - The input string containing the value to convert. - - - - Returns a string that represents the current . - - - - - Determines whether two object instances are equal. - - The object to compare with the current instance of the . - true if the specified object is equal to the current ; otherwise, false. - - - - Determines whether two object instances are equal. - - The instance of to compare with the current instance of the . - true if the specified instance is equal to the current ; otherwise, false. - - - - Serves as a hash function for a particular type. - - A hash code for the current . - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Indicate whether two are not equal. - - The first instance. - The second instance. - - - - Indicate whether two are equal. - - The first instance. - The second instance. - - - - Gets the client name. - - - - - Gets the provider name. - - - - - Gets a md5 hash code for the current instance of the . - - - - - OAuth client for Google. - - -

Register and Configure a Google Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Google Developers Console and Create Project. - - Create new project button - - Enter the project name and click the Create. - - Create new project form - - - Click to the Credential menu in the APIs & OAuth. - - - Credential menu - - - For desktop application, click the Create new Client ID, select Installed application and Other. - - - Click the Create Client ID to complete. - - - Create new Client ID for desktop application - - - You will get the Client ID and Client Secret. - Use this for creating an instance of the . - - - Create new Client ID for desktop application - - - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - For web projects create another Client ID. In the form select the Web application and specify return addresses. - - Create new Client ID for web application - - - For more details, please visit Google Developers Console Help. - -
- - The following example shows how to use the in Console Applications. - For desktop applications, the user will need to manually enter authorization code. - - class Program - { - static void Main(string[] args) - { - try - { - var google = new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - // open the login page in browser - System.Diagnostics.Process.Start(google.AuthorizationUrl); - - // waiting of entering the access code - string code = ""; - while (String.IsNullOrEmpty(code)) - { - Console.WriteLine("Enter access code:"); - code = Console.ReadLine(); - } - - Console.WriteLine(); - - // set authorization code - google.AuthorizationCode = code; - // get user info - var user = google.GetUserInfo(); - Console.WriteLine("User ID: {0}", user.UserId); - Console.WriteLine("Name: {0}", user.DisplayName); - Console.WriteLine("Email: {0}", user.Email); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - Console.ReadKey(); - } - } - - - Module Module1 - - Sub Main() - Try - Dim google As New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ' open the login page in browser - System.Diagnostics.Process.Start(google.AuthorizationUrl) - - ' waiting of entering the access code - Dim code As String = "" - Do While String.IsNullOrEmpty(code) - Console.WriteLine("Enter access code:") - code = Console.ReadLine() - Loop - - ' set authorization code - google.AuthorizationCode = code - - ' get user info - Dim user As UserInfo = google.GetUserInfo() - Console.WriteLine("User ID: {0}", user.UserId) - Console.WriteLine("Name: {0}", user.DisplayName) - Console.WriteLine("Email: {0}", user.Email) - Catch ex As Exception - Console.WriteLine(ex.Message) - End Try - Console.ReadKey() - End Sub - - End Module - - Result of the program is shown in the images below. - Log in with Google - Access code - User info - In a web projects you can use the and . - The following example shows how use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-fscjqht7ou30a75gjkde1eu1brsvbqkn.apps.googleusercontent.com", - "SI5bIZkrSB5rO03YF-CdsCJC" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-fscjqht7ou30a75gjkde1eu1brsvbqkn.apps.googleusercontent.com", - "SI5bIZkrSB5rO03YF-CdsCJC" - ) - ) - End Sub - - The GoogleLoginResult method will handle authorization result. - - public ActionResult GoogleLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function GoogleLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Google. - - public ActionResult GoogleLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Google", Url.Action("GoogleLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function GoogleLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Google", Url.Action("GoogleLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the GoogleLogin method. - - @Html.ActionLink("Log in with Google", "GoogleLogin") - - - - - - - - - - - - - - - - - - - - - - -
- - - Represents base properties and method for OAuth 2.0 client. - - - For more details, please visit . - - - - - Represents base class for OAuth client classes. - - - - - Initializes a new instance of the class. - - The address for login. - The address for the access token. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - - is null or empty. - -or- - is null or empty. - -or- - is null or empty. - -or- - is null or empty. - - - - - Redirects a client to the Authorization URL. - - - Use this method only for web applications (ASP .NET). - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Gets the access token from the remote server. - - - This is method is implemented at the protocol level ( & ). - - The is null or empty. - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Gets the user details via API of the provider. - - May contain an access token, which will have to be used in obtaining information about the user. - - This is method is implemented at the client level. - - - - - Creates a shallow copy of the current object. - - The query parameters for new copy object. - The new return URL for new copy object. - A shallow copy of the current object. - - Method creates a copy of the current object, removes tokens, change the return address, query parameters and state. - Unfortunately, I made a mistake in architecture, so I had to make this method. - - - - - - Creates a shallow copy of the current object. - - A shallow copy of the current object. - - Method creates a copy of the current object, removes tokens, change the return address, query parameters and state. - Unfortunately, I made a mistake in architecture, so I had to make this method. - - - - - - Returns the specified access token or the current access token. - - May contain an access token, which will be refunded. - Indicates the need to check the parameter refresh_token in the access token. Default: false. - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - - - - Unique provider name. - - - Client classes are required to implement this property. - The provider name must be unique. - - - - public override string ProviderName - { - get - { - return "KGB"; - } - } - - - - - - Gets the endpoint of the authorization. - - - This property is implemented at the protocol level ( & ). - - - - - Gets or sets an access token. - - - - - Gets an access token value. - - - - - Gets or sets access code for access token requests. - - - - - Gets or sets unique request identifier. - For clients the value sets is automatically. - - - - - Gets or sets the application identifier. - - - - - Gets or sets the application secret key. - - - - - Gets or sets the base address for login. - - - - - Gets or sets the address for the access token. - - - - - Gets the version of the OAuth protocol. - - - - - Gets or sets return URL. - - - At this address provider will return the user authorization results. - For many providers are needed configuration of the application on the provider website. - - - - - Gets or sets additional query parameters. - - - These parameters will be transferred to the provider. - - - - - Gets or sets a value indicating whether the current client supports revoking access token. - - - - - Gets or sets a value indicating whether the current client supports refreshing access token. - - - - - Initializes a new instance of the class. - - The address for login. - The address for the access token. - The application identifier. - The application secret key. - - - - Gets the access token from the remote server. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - The scope of the access request. - - - - - The deault scope. - - - - - The separator in the scope list. - - - - - Gets or sets grant type. - - - - - Gets or sets username if is password or client_credentials. - - - - - Gets or sets password if is password or client_credentials. - - - - - Gets the endpoint of the authorization. - - - - - Initializes a new instance of the . - - The Client ID obtained from the Google Developers Console. - The Client Secret obtained from the Google Developers Console. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - In order to Google returned the refresh_token, when receiving an access token, you must specify access_type=offline. - - - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - { - Parameters = new NameValueCollection { { "access_type", "offline" } } - } - ); - - - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) With _ - { - .Parameters = New NameValueCollection() From {{"access_type", "offline"}} - } - ) - - For more details, please see Google Documentation. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Google. - - - - - Return URL. - - - - - OAuth client for Amazon. - - -

Register and Configure Amazon Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - You need to register as developer in the App Console. - - - Sign in to the App Console - - - In the App Console register new application. - - - Register new application - - - Specify one or more return URLs. Access to any other address will be denied. - - - NOTE: Amazon supports only addresses over HTTPS (excluding localhost). - - - For example: - - https://hamster.example.org/Home/ExternalLoginResult - http://localhost:59962/Home/ExternalLoginResult - http://localhost/ - - - - Allowed Return URLs - - Do not forget to save your changes. - Use application Client ID and Client Secret when creating an instance of the class. - - Allowed Return URLs - - - OAuthManager.RegisterClient - ( - new AmazonClient - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New AmazonClient _ - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ) - - - For more details, please see Amazon Developer Documentation. - -
- - The following example shows how to add the Amazon OAuth Client to ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new AmazonClient - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New AmazonClient _ - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ) - End Sub - - The ExternalLoginResult method will handle authorization result. - - public ActionResult ExternalLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function ExternalLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Now you can easily redirect user to login page. - - // NOTE: use httpS scheme for real websites - string authUrl = OAuthWeb.GetAuthorizationUrl("Amazon", Url.Action("ExternalLoginResult", "Home", null, null, Request.Url.Host)); - // for example, MVC redirection from Action: - // return Redirect(authUrl); - - - ' NOTE: use httpS scheme for real websites - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Amazon", Url.Action("ExternalLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - ' for example, MVC redirection from Action - ' Return Redirect(authUrl) - - Result shown in the images below. - Amazon Sign in - Amazon User Info - - - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the class. - - The client ID obtained from the App Console. - The client secret obtained from the App Console. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Amazon. - - - - - OAuth client for Microsoft Live. - - -

Register and Configure a Live Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Live Connect App Management and Create a New Application. - - Create a New Application - - Specify the application name, read terms of use and click the I accept. - - Create a New Application form - - Open the App Settings and add return URLs. You can't use localhost. - - Redirect URLs - - On the App Settings page, you can found Client ID and Client Secret. - - Use this for creating an instance of the . - - - Cleint ID and Client Secret - - - OAuthManager.RegisterClient - ( - new LiveClient - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New LiveClient _ - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ) - - - For more details, please visit to the MSDN. - -
- - The following example shows how to add the Microsoft Live OAuth Client to ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new LiveClient - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New LiveClient _ - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ) - End Sub - - The LiveLoginResult method will handle authorization result. - - public ActionResult LiveLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function LiveLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Microsoft Live. - - public ActionResult LiveLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Live", Url.Action("LiveLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function LiveLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Live", Url.Action("LiveLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the LiveLogin method. - - @Html.ActionLink("Log in with Microsoft Live", "LiveLogin") - - Result shown in the images below. - Microsoft Live Sign in - User Info - - - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the Live Connect App Management. - The Client Secret obtained from the Live Connect App Management. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - In order to Microsoft Live returned the refresh_token, when receiving an access token, you must specify the scope wl.offline_access. - - - OAuthManager.RegisterClient - ( - new LiveClient - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - { - Scope = "wl.offline_access" - } - ); - - - OAuthManager.RegisterClient _ - ( - New LiveClient _ - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) With { .Scope = "wl.offline_access" } - ) - - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Live. - - - - - OAuth client for GitHub. - - -

Register and Configure a GitHub Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - - Register a new OAuth application. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new GitHubClient - ( - "e14122695d88f5c95bce", - "cde23ec001c5180e01e865f4efb57cb0bc848c16" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New GitHubClient _ - ( - "e14122695d88f5c95bce", - "cde23ec001c5180e01e865f4efb57cb0bc848c16" - ) - ) - - - For more details, please see GitHub Development Guides. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the GitHub Applications. - The Client Secret obtained from the GitHub Applications. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: GitHub. - - - - - OAuth client for Dropbox. - - -

Register and Configure a Dropbox Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Dropbox App Console and Create app. - Choose the Dropbox API app type. - - In the application settings you can found App key and App secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new DropboxClient - ( - "0le6wsyp3y085wy", - "48afwq9yth83y7u" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New DropboxClient _ - ( - "0le6wsyp3y085wy", - "48afwq9yth83y7u" - ) - ) - - - For more details, please visit Dropbox Platform Help. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The App key obtained from the Dropbox App Console. - The App secret obtained from the Dropbox App Console. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Unique provider name: Dropbox. - - - - - OAuth client for Foursquare. - - -

Register and Configure a Foursquare Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Foursquare App and Create app. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new FoursquareClient - ( - "LHYZN1KUXN50L141QCQFNNVOYBGUE3G3FCWFZ3EEZTOZHY5Q", - "HWXYFLLSS2IUQ0H4XNCDAZEFZKIU3MZRP5G55TNBDHRPNOQT" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New FoursquareClient _ - ( - "LHYZN1KUXN50L141QCQFNNVOYBGUE3G3FCWFZ3EEZTOZHY5Q", - "HWXYFLLSS2IUQ0H4XNCDAZEFZKIU3MZRP5G55TNBDHRPNOQT" - ) - ) - - - For more details, please visit Foursquare for Developers. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the Foursquare Apps. - The Client Secret obtained from the Foursquare Apps. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Foursquare. - - - - - OAuth client for SoundCloud. - - -

Register and Configure a SoundCloud Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the SoundCloud for Developers and Register a new app. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new SoundCloudClient - ( - "42b58d31e399664a3fb8503bfcaaa9ba", - "f9d85648da59fb95ec131b40c7645c31" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New SoundCloudClient _ - ( - "42b58d31e399664a3fb8503bfcaaa9ba", - "f9d85648da59fb95ec131b40c7645c31" - ) - ) - - - For more details, please visit SoundCloud for Developers. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the SoundCloud Applications. - The Client Secret obtained from the SoundCloud Applications. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: SoundCloud. - - - - - OAuth client for SourceForge. - - -

Register a SourceForge Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Consumer ID and Consumer Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the SourceForge Authorized Applications and Register New Application. - - You can see Consumer Key and Consumer Secret, use this for creating an instance of the . - - - OAuthManager.RegisterClient - ( - new SourceForgeClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New SourceForgeClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - - - For more details, please visit Allura API. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Represents base properties and method for OAuth 1.0 client. - - - For more details, please visit . - - - - - Initializes a new instance of the class. - - The address for the request token. - The address for login. - The address for the access token. - The application identifier. - The application secret key. - The name of hashing algorithm to calculate the signature: HMAC-SHA1 (default) or PLAINTEXT. - The is null or empty. - - - - Gets base string of the signature for current request. - - For more details, please visit - - - - Gets signature for the current request. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - - - - Gets the request token from the remote server. - - - - - Gets the access token from the remote server. - - - - - Gets or sets the address for the request token. - - - - - Get the authorization parameters. - - - - - Gets the endpoint of the authorization. - - - - - Gets or sets the request token. - - - - - Initializes a new instance of the . - - The Consumer Key obtained from the SourceForge OAuth applications. - The Consumer Secret obtained from the SourceForge OAuth applications. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - Name of the user whose data should be obtained. - - - - Gets the request token from the remote server. - - - - - Gets the access token from the remote server. - - - - - Unique provider name: SourceForge. - - - - - OAuth client for Yahoo. - - -

Register and Configure a Yahoo Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Consumer ID and Consumer Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open Yahoo Developer Network and Create a Project. - - In the application settings you can found Consumer Key and Consumer Secret. - Use this for creating an instance of the class. - - Note that Yahoo! does not work with the localhost. Use only a real servers. Make sure that your application on the Yahoo! dashboard configured correctly. - Yahoo! has a pretty flimsy OAuth interface. If something is done or configured incorrectly, the work will be nothing. But in general, the client is tested and works. - - OAuthManager.RegisterClient - ( - new YahooClient - ( - "dj0yJmk9Qm1vZ3p2TmtQUm4zJmQ9WVdrOU4wbGlkWGxJTkc4bWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD0xZQ--", - "a55738627652db0acfe464de2d9be13963b0ba1f" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New YahooClient _ - ( - "dj0yJmk9Qm1vZ3p2TmtQUm4zJmQ9WVdrOU4wbGlkWGxJTkc4bWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD0xZQ--", - "a55738627652db0acfe464de2d9be13963b0ba1f" - ) - ) - - - For more details, please visit Yahoo Developer Network. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Consumer Key obtained from the Yahoo Developer Dashboard. - The Consumer Secret obtained from the Yahoo Developer Dashboard. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Access token must contain the user ID in the parameter xoauth_yahoo_guid. - - - - - Gets the access token from the remote server. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - (!) - To update the access token, you must specify the return address that was used in obtaining the access token. - - - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - An exception occurs if there is no authorization code. - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - Callback address that was used in obtaining the access token. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - (!) - To update the access token, you must specify the return address that was used in obtaining the access token. - - - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - An exception occurs if there is no authorization code. - - - - Unique provider name: Yahoo. - - - - - OAuth client for LinkedIn. - - -

Register and Configure a LinkedIn Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open and sigin to the LinkedIn for Developers, and Add new app. - - In the application settings you can found Api Key and Secret Key. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new LinkedInClient - ( - "75vufylz829iim", - "VOf14z4T1jie4ezS" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New LinkedInClient _ - ( - "75vufylz829iim", - "VOf14z4T1jie4ezS" - ) - ) - - - For more details, please visit LinkedIn for Developers. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Api Key obtained from the LinkedIn Dashboard. - The Secret Key obtained from the LinkedIn Dashboard. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: LinkedIn. - - - - - OAuth client for Tumblr. - - -

Register and Configure a Tumblr Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Tumblr Dashboard, and Register an application. - - In the application settings you can found Consumer Key and Consumer Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new TumblrClient - ( - "2EZbsj2oF8OAouPlDWSVnESetAchImzPLV4q0IcQH7DGKECuzJ", - "4WZ3HBDwNuz5ZDZY8qyK1qA5QFHEJY7gkPK6ooYFCN4yw6crKd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New TumblrClient _ - ( - "2EZbsj2oF8OAouPlDWSVnESetAchImzPLV4q0IcQH7DGKECuzJ", - "4WZ3HBDwNuz5ZDZY8qyK1qA5QFHEJY7gkPK6ooYFCN4yw6crKd" - ) - ) - - - For more details, please visit Tumblr API Documentation. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Consumer Key obtained from the Tumblr Dashboard. - The Consumer Secret obtained from the Tumblr Dashboard. - - - - Gets an user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Tumblr. - - - - - OAuth client for Instagram. - - -

Register and Configure a Instagram Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Register as Developer and Register new Client ID. - - In the application settings you can found Client ID and Client Key. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new InstagramClient - ( - "215a1941ebed4e4fa74e94dd84762836", - "ba53a710e1624870bc066e7a9ae38601" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New InstagramClient _ - ( - "215a1941ebed4e4fa74e94dd84762836", - "ba53a710e1624870bc066e7a9ae38601" - ) - ) - - - For more details, please visit Instagram Developer Documentation. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the Instagram Manage Clients. - The Client Secret obtained from the Instagram Manage Clients. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Instagram. - - - - - OAuth client for CodeProject. - - -

Register and Configure a CodeProject Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - - Register a new client. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new CodeProjectClient - ( - "92mWWELc2DjcL-6tu7L1Py6yllleqSCt", - "YJXrk_Vzz4Ps02GqmaUY-aSLucxh4kfLq6oq0CtiukPfvbzb9yQG69NeDr2yiV9M" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New CodeProjectClient _ - ( - "92mWWELc2DjcL-6tu7L1Py6yllleqSCt", - "YJXrk_Vzz4Ps02GqmaUY-aSLucxh4kfLq6oq0CtiukPfvbzb9yQG69NeDr2yiV9M" - ) - ) - - - For more details, please see CodeProject API Documentation. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the CodeProject Web API Clients. - The Client Secret obtained from the CodeProject Web API Clients. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: CodeProject. - - - - - OAuth client for Assembla. - - -

Register and Configure an Assembla Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - - Register a new OAuth application. - - In the application settings you can found Application ID and Application Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new AssemblaClient - ( - "bOS4QkXnmr5jhdacwqjQXA", - "701ee6dedf74fc4ad75bfa7476666a2f" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New AssemblaClient _ - ( - "bOS4QkXnmr5jhdacwqjQXA", - "701ee6dedf74fc4ad75bfa7476666a2f" - ) - ) - - - For more details, please visit Assembla API Documentation Site. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Application ID obtained from the Assembla Applications Manager. - The Application Secret obtained from the Assembla Applications Manager. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Assembla. - - - - - The list of access token types. - - - - - Bearer - - - - - OAuth - - - - - The list of authorization type. - - - - - Basic - - - - - Bearer - - - - - Digest - - - - - OAuth - - - - - The list of the types a HTTP parameters. - - - - - Unformed parameter. - - - - - Parameter of the query string. - - - - - Parameter of the form. - - - - - File. - - - - - Body of the request. - - - - - Very sexy list. - - - - - No sex. - - :o) - - - - Male. - - - - - Female. - - - - - Programmer. - - - - - Deep Thought. - - - - - The list of url encding methods. - - - - - Without encoding. - - - - - for POST requests when a conetent-type is x-www-form-urlencoded. - And for other requests. - - - - - x-www-form-urlencoded (spaces encoded as plus (+) signs). - - - - - RFC 3986 (spaces encoded as %20). - - - - - Represents the access token exception. - - - - - The exception that is thrown when an error occurs while accessing the network. - - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The content type of the server request result. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The content type of the server request result. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - The HTTP headers of the output. - The HTTP status code of the output. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Instance of the . - - - - - Gets the HTTP status code of the output returned to the client. - - - - - Gets the content type of the response. - - - - - Gets the http headers of the response. - - - - - Initializes a new instance of the class with a specified message. - - The error message that explains the reason for this exception. - - - - The exception that is thrown when server of API returns error. - - - - - Initializes a new instance of the class with a specified and the exception that is the cause of this exception. - - The result of the request. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class with a specified and error message. - - The result of the request. - The error message that explains the reason for this exception. - - - - Initializes a new instance of the class with a specified error message. - - The error message that explains the reason for this exception. - - - - Initializes a new instance of the class with a specified error message and the exception that is the cause of this exception. - - The error message that explains the reason for this exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - The content type of the server request result. - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - The content type of the server request result. - - - - Initializes a new instance of the class with a specified server request result, content type and a error message. - - The result of the request. - The error message that explains the reason for this exception. - The content type of the server request result. - - - - Initializes a new instance of the class with a specified server request result, content type and a error message. - - The result of the request. - The error message that explains the reason for this exception. - The content type of the server request result. - - - - OAuth client for Facebook. - - -

Register and Configure a Facebook Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - You need to register as developer. - - Open the Facebook Developers and Create a New App. - - Create new application menu - - Specify the application name and click the Create App. - - Create new application form - - - In the application dashboard you can found App ID and App Secret, this is Client ID and Client Secret. - Use this for creating an instance of the class. - - - App ID and App Secret - - - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - You can use the App ID and App Secret for desktop, mobile and web projects. -

The application availability

- - To manage the status of the application, you must provide contact information. - - - Enter a contact email on the Settings page. - - - Contact Email - - - And now, you can change availability status of the application on the Status & Review page. - - - Make App Public - -

Configure application for web projects

- For web projects, configure return URLs. - - Open the application Settings and click Advanced tab. - - - Advanced tab - - - You must add the return URLs to the Valid OAuth redirect URIs field of the Security section. - - Do not forget to save your changes. - NOTE: If the application will be used for web and desktop, then also add URL: https://www.facebook.com/connect/login_success.html. - NOTE: Enable Client OAuth Login if it's disabled. - - Valid OAuth redirect URIs - - - For more details, please see Facebook Developer Documentation. - -
- - The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Insert a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // facebook client registration - OAuthManager.RegisterClient - ( - new FacebookClient - ( - // app id - "1435890426686808", - // app secret - "c6057dfae399beee9e8dc46a4182e8fd" - ) - { - // display=popup - to open a popup window - Parameters = new NameValueCollection { { "display", "popup" } } - } - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' facebook client registration - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) With _ - { - .Parameters = New NameValueCollection() From {{"display", "popup"}} - } - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Insert a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("facebook")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("facebook")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - - Result of the program is shown in the images below. - Log in with Facebook - Facebook User Info - - - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The App ID obtained from the Facebook Developers. - The App Secret obtained from the Facebook Developers. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - For more details, please see User method in Guide of Facebook Graph API. - - - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Unique provider name: Facebook. - - - - - Return URL. - - - - - OAuth client for Odnoklassniki. - - - Odnoklassniki is a social network service for classmates and old friends. It is popular in Russia and CIS. -

Register and Configure a Odnoklassniki Site

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open My Games page and click My Uploaded Games. - - My Games in the footer menu - - - My Uploaded Games - - Click Add App. - - Add App button - - Enter the Title, Shortname, Description, Image link and App link. Select Application type (External type) and Permission. - - - (!) - - It is important to provide a link to the application (App link).
- You must use this link as the return URL. Even for desktop applications.
- You can use localhost for desktop applications.
- It is important to specify the type of application: External. -
-
-
- - App form - - In your email box you will find email message with the Client ID, Client Secret and Public key. - - Email message - - - Use this for creating an instance of the . - - - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ) - - - For more details, please visit to the Odnoklassniki API Documentation. - -
- -

Windows Forms

- The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Add a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // odnoklassniki client registration - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - // application ID - "1094959360", - // sectet key - "E45991423E8C5AE249B44E84", - // public key - "CBACMEECEBABABABA" - ) { ReturnUrl = "http://localhost" } // return url - it's important - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' odnoklassniki client registration - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) With { .ReturnUrl = "http://localhost" } - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Odnoklassniki")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Odnoklassniki")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - -

ASP .NET MVC

- The following example shows how to use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - // application ID - "1094959360", - // sectet key - "E45991423E8C5AE249B44E84", - // public key - "CBACMEECEBABABABA" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ) - End Sub - - The OdnoklassnikiLoginResult method will handle authorization result. - - public ActionResult OdnoklassnikiLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function OdnoklassnikiLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Odnoklassniki. - - public ActionResult OdnoklassnikiLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Odnoklassniki", Url.Action("OdnoklassnikiLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function OdnoklassnikiLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Odnoklassniki", Url.Action("OdnoklassnikiLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the OdnoklassnikiLogin method. - - @Html.ActionLink("Log in with Odnoklassniki", "OdnoklassnikiLogin") - -

ASP .NET WebForms

- The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - // application ID - "1094959360", - // sectet key - "E45991423E8C5AE249B44E84", - // public key - "CBACMEECEBABABABA" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - Response.Write(String.Format("Email: {0}", user.Email)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Response.Write(String.Format("Email: {0}", user.Email)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkOdnoklassniki" runat="server" - Text="Log in with Odnoklassniki" onclick="lnkOdnoklassniki_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkOdnoklassniki_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Odnoklassniki", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkOdnoklassniki_Click(sender As Object, e As EventArgs) Handles lnkOdnoklassniki.Click - OAuthWeb.RedirectToAuthorization("Odnoklassniki", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID. - The Client Secret. - The Public Key. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - - Unique provider name: Odnoklassniki. - - - - - Public Key for access to API. - - - - - Represents a method that is called for parsing item of the API data. - - The instance to parse. - - - - References a method to be called when a corresponding asynchronous web request completes. - - The result of the asynchronous web request. - - - - Represents the error results of the query. - - - - - Initializes a new instance of the class. - - The request results. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets a value indicating whether the current request result is successful or not. - - Always has the value false. - - - - The exception that is thrown when a resource owner or authorization server denied the request. - - - - - The exception that is thrown when a user fails to login. - - - - - Initializes a new instance of the class with a specified error message. - - The error message that explains the reason for this exception. - - - - Initializes a new instance of the class with a specified error message and the exception that is the cause of this exception. - - The error message that explains the reason for this exception. - - - - The exception that is thrown when trying to access an unregistered OAuth client. - - - Use the for OAuth clients registration. - - - The following example illustrates a situation in which the is thrown. - - string url = OAuthWeb.GetAuthorizationUrl("facebook"); - // ... - - - Dim url As String = OAuthWeb.GetAuthorizationUrl("facebook"); - ' ... - - ClientIsNotRegisteredException - To solve the problem enough to register the client. - - // facebook client registration - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - ' facebook client registration - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - Enjoy! - - string url = OAuthWeb.GetAuthorizationUrl("facebook"); - // ... - - - Dim url As String = OAuthWeb.GetAuthorizationUrl("facebook"); - ' ... - - - - - - Initializes a new instance of the class. - - - - - Represents the empty results of the query. - - - The class is used to determine sends a request to the remote server or not. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets a value indicating whether the current request result is successful or not. - - Always has the value false. - - - - The exception that is thrown when you attempt to register the already registered client. - - - - - Initializes a new instance of the class. - - The name of the provider. - - - - Initializes a new instance of the class. - - The name of the provider and client. - - - - Gets an error message. - - - - - The exception that is thrown when has more than one . - - - - - Initializes a new instance of the . - - - - - The exception that is thrown when HttpContext.Current is null (Nothing in Visual Basic). - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Initializes a new instance of the class. - - - - - The exception occurs when you try to access a provider by provider name. If the name is incorrect, or does not exist. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with a specified error message. - - The error message that explains the reason for this exception. - An object array that contains zero or more objects to format. - - - - The exception that is thrown when adding a to the and collection has one a . - - - - - Initializes a new instance of the . - - - - - Represents a HTTP authorization header. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with specific authorization type and value. - - - - - Initializes a new instance of the class from specific source. - - - - - Removes the value with the specified key from the . - - The key of the element to remove. - - true if the element is successfully found and removed; otherwise, false. - This method returns false if key is not found in the or is not collection. - - - - - Returns OAuth string of the current object for Authorization header. - - - - - Invoked before sending a web request. - - HTTP Method of the request: POST, PUT, GET or DELETE. - URL of the web request. - The value of the Content-Type HTTP header. - >Parameters of the web request. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Gets or sets authorization method. - - - - - Gets or sets parameters of the authorization. - - - - - Authorization parameters. - - - - - Sorted authorization parameters. - - - - - Gets or sets the value associated with the specified key. - - The key of the value to get or set. - - - - Implements a file to transfer in a HTTP request. - - - - - Implements a HTTP paramter. - - - - - Initializes a new instance of the class. - - The name of the parameter. - The value of the parameter. - The content-type of the parameter. - - - - Initializes a new instance of the class. - - The name of the parameter. - The value of the parameter. - The type of the parameter. - The content-type of the parameter. - - - - Returns a string that represents the current parameter. - - - - - Gets or sets parameter name. - - - - - Gets or sets parameter value. - - - - - Gets or sets Content-Type. - - - - - Gets or sets type of the parameter. - - - - - Initializes a new instance of the class. - - Content of the file. - Name of the file. - The name of the parameter. - - - - Initializes a new instance of the class. - - The name of the parameter. - The posted file. - - - - Initializes a new instance of the class. - - Content of the file. - Name of the file. - The name of the parameter. - MIME type of the file. - - - - Gets or sets the filename. - - - - - Collection of HTTP parameters. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - The collection of parameters. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Initializes a new instance of the class. - - The body of a request. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Initializes a new instance of the class. - - The body of a request. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Initializes a new instance of the class. - - The array of parameters. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Adds a parameter to the end of the collection. - - The parameter to be added to the collection. - - - - Adds a parameter to the end of the collection. - - The name of parameter. - The parameter value. - - - - Adds a to the end of the collection. - - The name of the parameter. - The parameter value. - - - - Adds a to the end of the collection. - - The name of the parameter. - The value of the parameter. - The type of the parameter. - - - - Adds a to the end of the collection. - - The name of parameter. - The posted file. - - - - Adds a to the end of the collection. - - The posted file. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The Content-Type of the file. - The content of the file. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The content of the file. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The Content-Type of the file. - The file stream. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The file stream. - - - - Adds a to the end of the collection. - - The content of the request. - - - - Adds a to the end of the collection. - - The content of the request. - - - - Adds a to the end of the collection. - - The content of the request. - - - - Adds the items of the specified collection to the end of the current instance of the . - - The collection whose items should be added to the end of the current instance of the . - - - - Adds a to the end of the collection. - - The name of parameter. - The parameter value. - - - - Adds a to the end of the collection. - - The name of parameter. - The parameter value. - - - - Adds file as content to the end of the collection. - - The posted file. - - - - Adds content to the end of the collection. - - The Content-Type of the . - The content value. - - - - Inserts an element into the instance of the at the specified index. - - The zero-based index at which item should be inserted. - The to insert. - - - - Inserts the elements of a collection into the instance of the at the specified index. - - The zero-based index at which the new elements should be inserted. - The collection whose elements should be inserted into the instance of the . - - - - Removes the first occurrence of a specific parameter from the . - - The parameter to remove from the . - - true if is successfully removed; otherwise, false. - This method also returns false if was not found in the . - - - - - Removes all the elements that match the conditions defined by the specified predicate. - - The delegate that defines the conditions of the elements to remove. - The number of elements removed from the . - - - - Removes the element at the specified index of the . - - The zero-based index of the element to remove. - - - - Removes a range of elements from the . - - The zero-based starting index of the range of elements to remove. - The number of elements to remove. - - - - Removes all elements from the . - - - - - Updates status of the collection. - - - - - Checks parameters types. - - The type for checking. - - - - Returns a string query parameters encoded by default method (). - - - - - Returns a string of query parameters with a specified separator. - - The separator of query parameters. For example: & - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified separator and encoding parameters. - - The separator of query parameters. - The type of the encoder. - The types of parameters to be used. - - - - Copies elements of the to a new instance. - - The true value included into the results only the parameters. The default value is false - all parameters. - - - - Gets a body for the request. - - - - - Writes the parameters to the request. - - The instance of the request. - - - - Writes a file to the request. - - The name of the parameter. - The filename. - The Content-Type of the file. - The content of the file. - The output stream instance. - - - - Writes a form-data parameter to the request. - - The name of the parameter. - The value of the parameter. - The output stream instance. - - - - Writes any parameter to the request. - - The Content-Type of the . - The content value. - The instance of the output stream. - - - - The assignment operator for array of the . - - The array that will be used as the . - New instance of the . - - - - The assignment operator for the . - - The collection that will be used as the . - New instance of the . - - - - The assignment operator for the byte array. - - The byte array of the request body. - New instance of the . - - - - The assignment operator for the . - - The instance of the of the request body. - New instance of the . - - - - Gets a value indicating whether the current collection has a files. - - - - - Gets a value indicating whether the current collection has a . - - - - - Gets a boundary for a request. - - - - - Gets or sets code page for parameters encoding. - - - - - Implements a value of the HTTP paramter. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Returns an encoded string of the value. - - - - - Returns an encoded string of the value. - - - - - Returns a string that represents the current value. - - - - - Returns a byte array that represents the current value. - - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the array of the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Gets or sets value. - - - - - Implements a request body. - - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - The access token class for OAuth 2.0. - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Initializes a new instance of the class. - - Result of request to the OAuth server. - - - - Initializes a new instance of the class with a specified access token and refresh token. - - The access token. - The refresh token. - - - - Initializes a new instance of the class with a specified access token and refresh token. - - The access token. - The refresh token. - The token type. For example: bearer. Default: null. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Returns the . - - - - - Converts the specified string to an . - - A string containing an access token to parse. - A new instance. - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - The access token issued by the authorization server. - - - - - The lifetime in seconds of the access token. - - - - - The refresh token, which can be used to obtain new - access tokens using the same authorization grant. - - - - - The scope of the access token. - - - - - The type of the token issued. Value is case insensitive. - - - - - Represents the authorization grant type. - - - - - Using an authorization code to confirm the identity (grant type is authorization_code). - - - - - Using username and password (grant type is password). - - - - - Using basic authorization with username and password (grant type is client_credentials). - - - - - Using a token to refreshing the access token (grant type is refresh_token). - - - - - Initializes a new instance with a specified . - - The value of grant type. - - - - Returns a string that represents the current . - - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Gets or sets the value. - - - - - Gets a value indicating whether the current value is authorization_code or not. - - - - - Gets a value indicating whether the current value is password or not. - - - - - Gets a value indicating whether the current value is client_credentials or not. - - - - - Provides helpers methods for OAuth. - - - - - Unreserved characters for the method. - - - http://tools.ietf.org/html/rfc3986#page-13 - - - - - This is main helper class. - - - - - Percent encoding. - - The text to encode. - The object that specifies the encoding scheme. - - For more details, please see: - - - - - - - - - Percent encoding. - - The text to encode. - - - - Encodes a URL string using the specified encoding object. - - The text to encode. - The type of the encoder. - - - - Encodes a URL string using the specified encoding object. - - The text to encode. - The object that specifies the encoding scheme. - The type of the encoder. - - - - Encodes a string into JavaScript string. - - The string to encode. - - - - Generate timestamp for a signature (only for OAuth 1.0). - - - - The timestamp value MUST be a positive integer. Unless otherwise - specified by the server's documentation, the timestamp is expressed - in the number of seconds since January 1, 1970 00:00:00 GMT. - - For more details, please see: - - - - - Generate random key. - - - - - Compute MD5 hash. - - Value that must be processed. - - - - Converts the string value to its equivalent string representation that is encoded with base-64 digits. - - A composite format string for encoding to Base64. - An object array that contains zero or more objects to format. - The string representation, in base 64. - - - - Performs a request using a GET method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request using a POST method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for web request. - The value of the Content-Type HTTP header. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request using a PUT method. - - URL to which will be sent to the request. - Parameters to be passed to the request. - Authorization header value. - HTTP headers for the request. - The value of the Content-Type HTTP header. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request using a DELETE method. - - URL to which will be sent to the request. - Parameters to be passed to the request. - Authorization header value. - HTTP headers for the request. - Access token to be used in the request. - Returns an instance of the class, which contains the result of the request. - - Can not be used simultaneously and . Use only one of these parameters. - - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request. - - HTTP Method: POST (default), PUT, GET or DELETE. - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for web request. - The value of the Content-Type HTTP header. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Reads results of the web request to the string. - - instance. - - - - Performs an async request using a GET method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request using a POST method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - The value of the Content-Type HTTP header. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request using a PUT method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - The value of the Content-Type HTTP header. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request using a DELETE method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request. - - HTTP Method: POST (default), PUT, GET or DELETE. - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - The value of the Content-Type HTTP header. - A delegate that, if provided, is called when an async web request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Gets the value of the specified , if the is a . - - Source of data. - The key is to be obtained. - - - - Returns a string containing a number. - - The value for processing. - - - - Gets signature for the current request. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - The authorization parameters. - - - - Gets signature for the current request. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - The authorization parameters. - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Represents a class that extends the class by adding methods for use with query parameters. - - - - - Convert the to list of the . - - The . - - - - Returns a string of query parameters without a separator. - - The . - - - - Returns a string of query parameters with a specified separator. - - The . - The separator of query parameters. For example: & - - - - Returns a string of query parameters with a specified encoding parameters. - - The . - Disables parameters encoding. - - - - Returns a string of query parameters with a specified separator and encoding parameters. - - The . - The separator of query parameters. - Disables parameters encoding. - - - - Sorts the by alphabetically and returns a new . - - The . - - - - Removes the value with the specified key from the . - - The . - The key of the element to remove. - - - - Represents the request item to OAuth server. - - - - - Initializes a new instance of the class. - - The instance of the OAuth client. - The client name. - - - - Gets name of the client. - - - - - Gets instance of the OAuth client. - - - - - Gets date and time creation of the request. - - - - - Represents helper class for sessions management of OAuth. - - - Mainly the class is intended for web projects. - But you can use some methods of the class in desktop applications together with the WebBrowser control. - - The methods , - , - and - - will not work in desktop applications. - - - -

ASP .NET WebForms

- The following example shows how to use the in ASP .NET WebForms. - To redirect the user to the login page is used the method. - Processing of the authorization results is performed by . - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkTwitter" runat="server" - Text="Log in with Twitter" onclick="lnkTwitter_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkTwitter_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Twitter", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkTwitter_Click(sender As Object, e As EventArgs) Handles lnkTwitter.Click - OAuthWeb.RedirectToAuthorization("Twitter", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - -

Windows Forms

- The following example shows how to use the in desktop applications. - Methods redirection in Windows Forms applications do not work. To get the address of the authorization is used. - To test the example, create a new Windows Forms project with two forms. Add a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // mail.ru client registration - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' mail.ru client registration - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - -
-
- - - Redirects current client to the authorization page of the specified provider. - - Provider name, through which it is necessary to authorize the current user. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider with specified parameters. - - Provider name, through which it is necessary to authorize the current user. - Additional parameters to be passed to the authorization query. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider, query parameters and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - Additional parameters to be passed to the authorization query. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider, query parameters and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - Additional parameters to be passed to the authorization query. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Returns the authorization URL of the specified provider. - - Provider name, through which it is necessary to authorize the current user. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider with specified parameters. - - Provider name, through which it is necessary to authorize the current user. - Additional parameters to be passed to the authorization URL. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider, query parameters and return URL. - - Provider name, through which it is necessary to authorize the current user. - Additional parameters to be passed to the authorization URL. - The address to which the user is redirected after the authorization. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider, query parameters and return URL. - - - The provider name, through which it is necessary to authorize the current user; or the name of the registered client. - - Additional parameters to be passed to the authorization URL. - The address to which the user is redirected after the authorization. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Verifies the authorization results for the current URL. - - - The method will not work in desktop applications. For desktop applications you can use the overloads or . - - - Returns the verification results. - - - - - Verifies the authorization results for the specified URL. - - Address at which to perform the verification. - - Returns the verification results. - - - - - Verifies the authorization results for the specified request identifier and the code of the authorization. - - Request identifier. - The authorization code received from the provider server. - - Returns the verification results. - - - This method is intended for internal use. It is recommended to use the overload or . - - - - - Verifies the authorization results for the current URL and removes the request from memory. - - - The method will not work in desktop applications. For desktop applications you can use the overloads or . - - - Returns the verification results. - - - - - Verifies the authorization results for the specified URL, and removes the request from memory. - - Address at which to perform the verification. - - Returns the verification results. - - - - - Verifies the authorization results for the specified request identifier and the code of the authorization, and removes the request from memory. - - Request identifier. - The authorization code received from the provider server. - - Returns the verification results. - - - This method is intended for internal use. It is recommended to use the overload or . - - - - - The access token class for OAuth 1.0. - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Initializes a new instance of the class. - - Result of request to the OAuth server. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Returns the . - - - - - Converts the specified string to an . - - A string containing an access token to parse. - A new instance. - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - The access token issued by the authorization server. - - - - - The access token issued by the authorization server. - - - - - Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. - - - - - Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. - - - - - Перезаписывает свойство CurrentUICulture текущего потока для всех - обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. - - - - - Поиск локализованного ресурса типа System.Drawing.Bitmap. - - - - - Ищет локализованную строку, похожую на Aleksey Sergeevich Nemiro is a Russian developer of applications and websites, - author of articles on programming and information technology. - - Aleksey was born on October 3, 1983 in the city of Vladivostok (Primorsky Krai, Russia). - In 2009, Aleksey migrated to the city of Yoshkar-Ola (Mari El, Russia). - - Started programming in 1998 on the G-Basic and QBasic. - - At various times worked with programming languages and technologies: - Visaul Basic, Delphi, C, Visual C++, Java, PHP, ASP VBScript and JScript [остаток строки не уместился]";. - - - - - Represents authorization parameters for OAuth 1.0. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with specific value. - - - - - Updates the nonce and the timestamp. - - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The query parameters. - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The query parameters. - - - - Gets or sets the consumer key. - - - - - Gets or sets the consumer secret. - - - - - Gets or sets the token. - - - - - Gets or sets the secret token. - - - - - Gets or sets the signature method. - - - - - Gets or sets the nonce. - - - - - Gets or sets the timestamp. - - - - - Gets or sets the version of the OAuth. - - - - - Gets or sets the signature. - - - - - Gets or sets the callback address. - - - - - Gets or sets the verifier code. - - - - - OAuth client for Mail.Ru. - - - Mail.Ru is a popular email service, search engine, social network, photo & video hosting, blogs and another services in Russia and CIS. -

Register and Configure a Mail.Ru Site

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Unfortunately, the interface is only in Russian. - You must have a confirmed account in Mail.Ru. - Open Sites page and click Connect a New Site. - - Create a New Site button - - Accept the terms of the agreement. - - Terms - - Enter the site name, URL and click the Next button. - - Site name and URL - - Download the receiver.html file and place it in the root directory of your site. - This step can be skipped (Пропустить). - - receiver.html file - - The last step you will find the Client ID and Client Secret. - - Use this for creating an instance of the . - - - Cleint ID and Client Secret - - - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - - - For more details, please visit to the Mail.Ru API Documentation. - -
- -

Windows Forms

- The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Add a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // mail.ru client registration - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' mail.ru client registration - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - - Result of the program is shown in the images below. - Log in with Mail.Ru - Mail.Ru User Info -

ASP .NET MVC

- The following example shows how to use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - End Sub - - The MailRuLoginResult method will handle authorization result. - - public ActionResult MailRuLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function MailRuLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Mail.Ru. - - public ActionResult MailRuLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Mail.Ru", Url.Action("MailRuLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function MailRuLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Mail.Ru", Url.Action("MailRuLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the MailRuLogin method. - - @Html.ActionLink("Log in with Mail.Ru", "MailRuLogin") - - NOTE: For proper processing, you will need to download and put on your site a receiver.html file. -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID. - The Client Secret. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - The access token must contain the user ID in the parameter x_mailru_vid. - - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Mail.Ru. - - - - - Return URL. - - - - - Represents helper class for management of OAuth clients. - - - You can use this class to register clients in your project. - - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Initializes the . - - - - - The method is called when the interval elapsed. - - Instance of the object that raised the event. - The event data. - - - - Adds the specified request to the collection. - - The unique request key. - The client name. - The client instance. - - - - Removes the request from collection. - - The unique request key to remove.. - - - - Registers the specified client in the application. - - The client instance. - is null or empty. - If you attempt to register the already registered client. - - - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Registers the specified client in the application. - - The client instance. - The any name of the client. For example: Test, Release, Project #1, Ku!, Example.org etc. - is null or empty. - If you attempt to register the already registered client. - - - OAuthManager.RegisterClient - ( - "Test", - new GoogleClient - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Test", - new FacebookClient - ( - "00000000000000", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - "Test", - New GoogleClient _ - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Test", - New FacebookClient _ - ( - "00000000000000", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Registers the specified client in the application. (the main method) - - The client instance. - The any name of the client. For example: Test, Release, Project #1, Ku!, Example.org etc. - is null or empty. - If you attempt to register the already registered client. - - - OAuthManager.RegisterClient - ( - "Test", - new GoogleClient - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Test", - new FacebookClient - ( - "00000000000000", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - "Test", - New GoogleClient _ - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Test", - New FacebookClient _ - ( - "00000000000000", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Registers the specified client in the application. - - The provider name. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - , or is null or empty. - Provider not found by . - - - OAuthManager.RegisterClient - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - OAuthManager.RegisterClient - ( - "facebook" - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ); - - - OAuthManager.RegisterClient _ - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - - OAuthManager.RegisterClient _ - ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - - - - - - Registers the specified client in the application. - - The provider name. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - List of scope that will be requested from the provider. Only for OAuth 2.0. - Additional parameters to be passed to the constructor of the client class. - Additional parameters that will be transferred to the provider website. - , or is null or empty. - Provider not found by . - The not suppored . - - - OAuthManager.RegisterClient - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - OAuthManager.RegisterClient - ( - "facebook" - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ); - - - OAuthManager.RegisterClient _ - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - - OAuthManager.RegisterClient _ - ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - - - - - - Registers the specified client in the application. - - The provider name. And may also contain any client name for for division into groups. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - Additional parameters to be passed to the constructor of the client class. - List of scope that will be requested from the provider. Only for OAuth 2.0. - Additional parameters that will be transferred to the provider website. - , or is null or empty. - Provider not found by . - The not suppored . - - - OAuthManager.RegisterClient - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - OAuthManager.RegisterClient - ( - "facebook" - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ); - - - OAuthManager.RegisterClient _ - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - - OAuthManager.RegisterClient _ - ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - - - You can register multiple clients to a single provider. - The following example shows how to do it. - - - var clientName = ClientName.Create("Debug", "Facebook"); - - OAuthManager.RegisterClient - ( - clientName - "000000000000000000", - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - ); - - clientName = ClientName.Create("Any name", "Facebook"); - - OAuthManager.RegisterClient - ( - clientName - "111111111111111111", - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - ); - - - Dim name As ClientName = ClientName.Create("Debug", "Facebook") - - OAuthManager.RegisterClient _ - ( - name, - "000000000000000000", - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - ) - - name As ClientName = ClientName.Create("Any name", "Facebook") - - OAuthManager.RegisterClient _ - ( - name, - "111111111111111111", - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - ) - - - - - - Checks registered provider with the specified name or not. - - The provider name or client name. - - - - Returns type of client by name. - - The provider name. - - - - Gets the list of all clients. - - - - - Gets the list of active requests. - - - - - Gets the list of registered clients. - - - - - Variants of the signature encryption. - - - - - HMAC-SHA1 - - - - - RSA-SHA1 - - - - - PLAINTEXT - - - - - Represents the signature of the request. This is a helper class to simplify debugging. - - - - - Initializes a new instance of the class. - - The name of hashing algorithm to calculate the signature: HMAC-SHA1 (default) or PLAINTEXT. - The secret key for encryption. - Base string of the signature. - - is not suppored. - - - - - Returns the of the current object. - - - - - Gets the secret key for encryption. - - - - - Gets the name of hashing algorithm to calculate the signature: HMAC-SHA1 or PLAINTEXT. - - - - - Get base string of the signature. - - - - - Gets the signature. - - - - - Represents the request token results. - - - - - Initializes a new instance of the class. - - The request result. - The address of the authorization. - The query parameters. Will be used in the formation of the authorization address. - - - - Returns the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets the OAuth token. - - - - - Gets the token secret. - - - - - The parameter is used to differentiate from previous versions of the protocol. - - - - - Gets the address of the authorization. - - - - - OAuth client for Twitter. - - -

Register and Configure a Twitter Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Consumer ID and Consumer Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Twitter Application Management and Create a New App. - - Create a New App button - - Fill out the form and click the Create your Twitter application. - For web project, set a Callback URL. - - Create a New App form - - - Open the application page and click to the API Keys. - - - API Keys link - - - You can see API Key and API secret, this is Consumer Key and Consumer Secret. - Use this for creating an instance of the . - - - Client ID and Client Secret - - - OAuthManager.RegisterClient - ( - new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - - - For more details, please visit Twitter Developers Documentation. - -
- -

Console Applications

- The following example shows how to use the in Console Applications. - For desktop applications, the user will need to manually enter authorization code. - - class Program - { - static void Main(string[] args) - { - try - { - var twitter = new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ); - - // open the login page in browser - System.Diagnostics.Process.Start(twitter.AuthorizationUrl); - - // waiting of entering the access code - string code = ""; - while (String.IsNullOrEmpty(code)) - { - Console.WriteLine("Enter access code:"); - code = Console.ReadLine(); - } - - Console.WriteLine(); - - // set authorization code - twitter.AuthorizationCode = code; - // get user info - var user = twitter.GetUserInfo(); - Console.WriteLine("User ID: {0}", user.UserId); - Console.WriteLine("Name: {0}", user.DisplayName); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - Console.ReadKey(); - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Module Module1 - - Sub Main() - Try - Dim twitter As New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ' open the login page in browser - System.Diagnostics.Process.Start(twitter.AuthorizationUrl) - - ' waiting of entering the access code - Dim code As String = "" - Do While String.IsNullOrEmpty(code) - Console.WriteLine("Enter access code:") - code = Console.ReadLine() - Loop - - ' set authorization code - twitter.AuthorizationCode = code - - ' get user info - Dim user As UserInfo = twitter.GetUserInfo() - Console.WriteLine("User ID: {0}", user.UserId) - Console.WriteLine("Name: {0}", user.DisplayName) - Catch ex As Exception - Console.WriteLine(ex.Message) - End Try - Console.ReadKey() - End Sub - - End Module - - Result of the program is shown in the images below. - Log in with Twitter - Access code - User info -

ASP .NET WebForms

- In a web projects you can use the and . - The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkTwitter" runat="server" - Text="Log in with Twitter" onclick="lnkTwitter_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkTwitter_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Twitter", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkTwitter_Click(sender As Object, e As EventArgs) Handles lnkTwitter.Click - OAuthWeb.RedirectToAuthorization("Twitter", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - - NOTE: Do not forget to adjust the Callback URL in the Twitter Application Settings. -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The API Key obtained from the Twitter Application Management. - The API Secret obtained from the Twitter Application Management. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Unique provider name: Twitter. - - - - - OAuth client for VK (VKontakte). - - - VK (VKontakte) is "Russian Facebook". :-) -

Register and Configure a VKontakte Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the VK App development and click Create an Application. - - Create an Application button - - Specify the application name and type, and click the Connect Application. - - Creating an application - - Confirm by SMS. - - Confirmation - - - In the Application Settings you can found Application ID and Secure key, this is Client ID and Client Secret. - Use this for creating an instance of the class. - - NOTE: Change application status to Application ON and visible to all. - - Application settings - - - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ) - - For web projects, enable Open API, set Site address and configure Base domain in the Open API section. - - Base domains - - - For more details, please see VK App development. - -
- -

Windows Forms

- The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Insert a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // vk(ontakte) client registration - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - // application id - "4457505", - // secure secret - "wW5lFMVbsw0XwYFgCGG0" - ) - { - // display=popup - to open a popup window - Parameters = new NameValueCollection { { "display", "popup" } } - } - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' vk(ontakte) client registration - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) With _ - { - .Parameters = New NameValueCollection() From {{"display", "popup"}} - } - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("vk")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("vk")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - - Result of the program is shown in the images below. - Log in with VK(ontakte) - VK User Info -

ASP .NET MVC

- The following example shows how to use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ) - End Sub - - The VkontakteLoginResult method will handle authorization result. - - public ActionResult VkontakteLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function VkontakteLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Vkontakte. - - public ActionResult VkontakteLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("vk", Url.Action("VkontakteLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function VkontakteLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("vk", Url.Action("VkontakteLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the VkontakteLogin method. - - @Html.ActionLink("Log in with VK(ontakte)", "VkontakteLogin") - -

ASP .NET WebForms

- The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkVkontakte" runat="server" - Text="Log in with VK(ontakte)" onclick="lnkVkontakte_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkVkontakte_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("vk", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkVkontakte_Click(sender As Object, e As EventArgs) Handles lnkVkontakte.Click - OAuthWeb.RedirectToAuthorization("vk", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Application ID obtained from the VK App development. - The Secure Key obtained from the VK App development. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - - Unique provider name: VK. - - - - - Return URL. - - - - - OAuth client for Yandex. - - - Yandex is a popular search engine in Russia and CIS. -

Register and Configure a Yandex Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the register new application page, fill out the form and click Save. - NOTE: Russian language is available on the yandex.ru - Specify the application name and set permissions. - - To access a users profile, select Yandex.Username: Date of birth; Email address; User name, surname and gender. - This minimum permissions that are required to work. - - For web project, set a Callback URI. - NOTE: For desktop applications set Callback URI to https://oauth.yandex.ru/verification_code. - - Register new application - - - In the next step you will see an Application ID and Application password, this is Client ID and Client Secret. - Use this for creating an instance of the . - - - Client ID and Client Secret - - - OAuthManager.RegisterClient - ( - new YandexClient - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New YandexClient _ - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ) - - - For more details, please visit Yandex OAuth Documentation. - -
- -

Console Applications

- The following example shows how to use the in Console Applications. - For desktop applications, the user will need to manually enter authorization code. - - class Program - { - static void Main(string[] args) - { - try - { - var yandex = new YandexClient - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ); - - // open the login page in browser - System.Diagnostics.Process.Start(yandex.AuthorizationUrl); - - // waiting of entering the access code - string code = ""; - while (String.IsNullOrEmpty(code)) - { - Console.WriteLine("Enter access code:"); - code = Console.ReadLine(); - } - - Console.WriteLine(); - - // set authorization code - yandex.AuthorizationCode = code; - // get user info - var user = yandex.GetUserInfo(); - Console.WriteLine("User ID: {0}", user.UserId); - Console.WriteLine("E-Mail: {0}", user.Email); - Console.WriteLine("Name: {0}", user.DisplayName); - Console.WriteLine("Birthday: {0}", user.Birthday); - Console.WriteLine("Sex: {0}", user.Sex); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - Console.ReadKey(); - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Module Module1 - - Sub Main() - Try - Dim yandex As New YandexClient _ - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ' open the login page in browser - System.Diagnostics.Process.Start(yandex.AuthorizationUrl) - - ' waiting of entering the access code - Dim code As String = "" - Do While String.IsNullOrEmpty(code) - Console.WriteLine("Enter access code:") - code = Console.ReadLine() - Loop - - ' set authorization code - yandex.AuthorizationCode = code - - ' get user info - Dim user As UserInfo = yandex.GetUserInfo() - Console.WriteLine("User ID: {0}", user.UserId) - Console.WriteLine("E-Mail: {0}", user.Email) - Console.WriteLine("Name: {0}", user.DisplayName) - Console.WriteLine("Birthday: {0}", user.Birthday) - Console.WriteLine("Sex: {0}", user.Sex) - Catch ex As Exception - Console.WriteLine(ex.Message) - End Try - Console.ReadKey() - End Sub - - End Module - - Result of the program is shown in the images below. - Log in with Yandex - Access code - User info -

ASP .NET WebForms

- In a web projects you can use the and . - The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new YandexClient - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New YandexClient _ - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("E-Mail: {0}<br />", user.Email)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("E-Mail: {0}<br />", user.Email)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkYandex" runat="server" - Text="Log in with Yandex" onclick="lnkYandex_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkYandex_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Yandex", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkYandex_Click(sender As Object, e As EventArgs) Handles lnkYandex.Click - OAuthWeb.RedirectToAuthorization("Yandex", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - - NOTE: Do not forget to adjust the Callback URI in the Yandex Application Settings. -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Application ID. - The Application Password. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Unique provider name: Yandex. - - - - - Return URL. - - - - - Implements a parameter of url. - - - - - Initializes a new instance of the class with a specified parameter name and value. - - The parameter value. - The parameter name. - - - - Represents property description of a class. - - - - - The data reader. - - - - - Initializes a new instance of the class. - - - - - Returns whether resetting an object changes its value. - - The component to test for reset capability. - - - - Gets the current value of the property on a component. - - The component with the property for which to retrieve the value. - - - - Resets the value for this property of the component to the default value. - - The component with the property value that is to be reset to the default value. - - - - Sets the value of the component to a different value. - - The component with the property value that is to be set. - The new value. - - - - Determines a value indicating whether the value of this property needs to be persisted. - - The component with the property to be examined for persistence. - - - - Gets a value indicating whether this property is read-only. - - - - - Gets the type of the property. - - - - - Gets the type of the component this property is bound to. - - - - - The for . - - - - - Initializes a new instance of the class. - - - - - Returns a collection of property descriptors for the object represented by this type descriptor. - - - - - The properties collection. - - - - - Additional type for references. - - - - - Represents the collection of the . - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the with a specified reference to parent. - - - - - Initializes a new instance of the by other an instance of the . - - - - - Adds the specified key and value to the collection. - - The key of the element to add. - The value of the element to add. - - - - Determines whether the collection contains the specified key. - - The key to locate in the collection. - is null. - - - - Removes the value with the specified key from the collection. - - The key of the element to remove. - - true if the element is successfully found and removed; otherwise, false. - - - - - Returns a string that represents the current . - - - - - Determines whether two object instances are equal. - - The object to compare with the current instance of the . - true if the specified object is equal to the current ; otherwise, false. - - - - Returns a string that represents the specified item of the . - - The item to converted. - - - - Returns a string that represents the specified instance. - - The value to converted. - - - - Adds the specified item to the . - - The item to add. - - - - Removes all items from the collection. - - - - - Determines whether the collection contains a specific value. - - The object to locate in the collection. - - - - Removes the first occurrence of a specific object from the collection. - - The object to remove from the collection. - - - - Gets the value associated with the specified key. - - The key whose value to get. - When this method returns, the value associated with the specified key, if the key is found; otherwise, the . - - - - [Is not implemented] Copies the elements of the collection to an , starting at a particular index. - - The one-dimensional that is the destination of the elements copied from collection. The must have zero-based indexing. - The zero-based index in array at which copying begins. - - - - Returns an enumerator that iterates through a collection. - - - - - Returns an enumerator that iterates through a collection. - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Returns instance from . - - The value from which will be returned the . - - - - Gets or sets items of the collection. - - - - - The reference to parent. - - - - - Gets or sets the value associated with the specified key. - - The key of the value to get or set. - - - - Gets or sets the element at the specified index. - - The zero-based index of the element to get or set. - - - - Gets a collection containing the keys in the collection. - - - - - Gets a collection containing the values in the collection. - - - - - Gets the number of elements contained in the collection. - - - - - Gets a collection containing the keys in the collection. - - - - - Gets a collection containing the values in the collection. - - - - - Gets a value indicating whether the collection is read-only. Always false. - - - - - Represents the user profile info. - - - - - Initializes a new instance of the class. - - The data source. - The mapping rules. - - - - Initializes a new instance of the class. - - The data source. - The mapping rules. - - - - Returns the or . - - - - - Gets or sets a collection containing the API request results. - - - - - Gets or sets the user ID. - - - - - Gets or sets the username. - - - - - Gets or sets the first name of the user. - - - - - Gets or sets the last name of the user. - - - - - Gets or sets the display name of the user. - - - - - Gets or sets user email address. - - - - - Gets or sets user phone. - - - - - Gets or sets user birthday. - - - - - Gets or sets user url. - - - - - Gets or sets user image url. - - - - - Gets or sets gender of the user. - - - - - Gets the first and last name. - - - - - Represents data mapping collection for API results. - - - - - Initializes a new instance of the class. - - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - The data type. - The data format. For example: "dd.MM.yyyy" for dates, or: "00" for numerics, etc. - Custom parser of the data. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - The data type. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - The data type. - The data format. For example: "dd.MM.yyyy" for dates, or: "00" for numerics, etc. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - Custom parser of the data. - - - - Represents data mapping item for API results. - - - - - Initializes a new instance of the class. - - - - - Gets or sets the key name in the data source. - - - - - Gets or set the property name in the destination object. - - - - - Gets or sets the data type of the property in the destination object. - - - - - Gets or sets the data format. - - - - - Gets or sets a custom parser of the data. - - - - - Implements a form parameter. - - - - - Initializes a new instance of the class with a specified parameter name and value. - - The parameter value. - The parameter name. - - - diff --git a/bin/net45/Nemiro.OAuth.dll b/bin/net45/Nemiro.OAuth.dll deleted file mode 100644 index 6feb7af2ab9a2fc5789526c0f0647aa1cda1ece6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126976 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 - - - Nemiro.OAuth - - - - - Represents base properties and method for access token results. - - - - - Represents the base class for results of remote requests. - - - - - The universal type that represents a value. - - - represents any type of data. - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the with a specified value. - - The value. - - - - Initializes a new instance of the with a specified value and attributes. - - The value. - The collection of an attributes. - - - - Initializes a new instance of the with a specified value and reference to parent. - - The value. - The instance of the . - - - - Initializes a new instance of the with a specified value, attributes and reference to parent. - - The value. - The collection of an attributes. - The instance of the . - - - - Copies items of the to a new Dictionary<string, object>. - - - A Dictionary<string, object> containing copies of the elements of the . - A null value, if the property is false or the is empty. - - - - - Copies items of the to a new . - - - A containing copies of the elements of the . - A null value, if the property is false or the is empty. - - - - - Returns a array that represents the current . - - - A array containing the current . - A null value, if the property and is false or the is empty. - - - - - Determines whether the contains the specified key. - - The key to locate in the . - true if the is not null and contains an element with the specified ; otherwise, false. - is null. - - - - Determines whether the contains the specified key. - - The key to locate in the . - true if the is not null and contains an element with the specified ; otherwise, false. - - - - Adds the specified key and value to the . - - The key of the element to add. - The value of the element to add. - - Returns the added element. - - - - If the current is not a collection ( is false), it will automatically be converted to the collection. - If the current is not empty, then it will be assigned a key ____ in a new collection. - - - - - - Adds the specified key and value to the . - - The key of the element to add. - The value of the element to add. - The reference to parent of the elemet to add. - - Returns the added element. - - - - If the current is not a collection ( is false), it will automatically be converted to the collection. - If the current is not empty, then it will be assigned a key ____ in a new collection. - - - - - - Removes the value with the specified key from the . - - The key of the element to remove. - - true if the element is successfully found and removed; otherwise, false. - This method returns false if key is not found in the or is not collection ( is false). - - - - - Parses the and converts to . - - The reference to the collection, which will be placed the result of parsing . - The for parsing. - The reference to parent. - - - - Returns the of the specified attribute. - - The name of the attribute whose value you want to get. - - - - Returns parent for new instance of . - - - - - Initializes a new instance. - - - - - Initializes a new instance with a specified . - - The value. - - - - Initializes a new instance with a specified and . - - The value. - The collection of an attributes. - - - - Initializes a new instance with a specified and reference to . - - The value. - The instance of the . - - - - Initializes a new instance with a specified , and reference to . - - The value. - The instance of the . - The collection of an attributes. - - - - Initializes an empty instance with a specified and reference to . - - The collection of an attributes. - The instance of the . - - - - Converts the specified JSON string to an . - - A string containing a JSON data to parse. - A new instance. - is null. - The length exceeds the value of . - The recursion limit defined by was exceeded. - contains an unexpected character sequence. - is a dictionary type and a non-string key value was encountered. - includes member definitions that are not available on the target type. - It is not possible to convert to the target type. - - - - Converts the specified XML string to an . - - A string containing a XML data to parse. - A new instance. - is null. - - - - Converts the specified parameters string to an . - - A string containing an url parameters to parse. - A new instance. - contains an CR or LF characters. - - If is null or empty, the function returns an instance. - - - - - Converts the specified JSON string to an . A return value indicates whether the conversion succeeded. - - A string containing a JSON data to parse. - If successful, this parameter takes the result of parsing data. - true if s was converted successfully; otherwise, false. - - - - Converts the specified XML string to an . A return value indicates whether the conversion succeeded. - - A string containing a XML data to parse. - If successful, this parameter takes the result of parsing data. - true if s was converted successfully; otherwise, false. - - - - Converts the specified url parameters string to an . A return value indicates whether the conversion succeeded. - - A string containing an url parameters to parse. - If successful, this parameter takes the result of parsing data. - true if s was converted successfully; otherwise, false. - - - - Indicates whether the specified value is null or an . - - The instance to test. - true if the parameter is null or is false; otherwise, false. - - - - Gets the underlying type code of the . - - - - - - Converts the value of this instance to an equivalent value using the specified culture-specific formatting information. - - An object that supplies culture-specific formatting information. - A value equivalent to the value of this instance. - - - - - - Converts the value this instance to an equivalent 8-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 8-bit unsigned integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent Unicode character using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A Unicode character equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A instance equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent number using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A number equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent double-precision floating-point number using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A double-precision floating-point number equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 16-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 16-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 32-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 32-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 64-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 64-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 8-bit signed integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 8-bit signed integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent single-precision floating-point number using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A single-precision floating-point number equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - A instance equivalent to the value of this instance. - - - - Converts the value of this instance to an of the specified that has an equivalent value, using the specified culture-specific formatting information. - - The to which the value of this instance is converted. - An interface implementation that supplies culture-specific formatting information. - An instance of type whose value is equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 16-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 16-bit unsigned integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 32-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 32-bit unsigned integer equivalent to the value of this instance. - - - - Converts the value of this instance to an equivalent 64-bit unsigned integer using the specified culture-specific formatting information. - - An interface implementation that supplies culture-specific formatting information. - An 64-bit unsigned integer equivalent to the value of this instance. - - - - Creates a new object that is a copy of the current instance. - - A new object that is a copy of this instance. - - - - Returns an enumerator that iterates through a collection. - - An object that can be used to iterate through the collection. - - - - Returns an enumerator that iterates through a collection. - - An System.Collections.IEnumerator<UniValue> object that can be used to iterate through the collection. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Serves as a hash function for a particular type. - - A hash code for the current . - - - - Returns a string that represents the current . - - - - - Determines whether two object instances are equal. - - The object to compare with the current instance of the . - true if the specified object is equal to the current ; otherwise, false. - - - - Determines whether two instances are equal. - - The to compare with the current instance of the . - true if the specified is equal to the current ; otherwise, false. - - - - Determines whether this instance and another specified object have the same value. - - The string to compare to this instance of the . - true if the value of the parameter is the same as this instance; otherwise, false. - - - - Determines whether this string and a specified object have the same value. A parameter specifies the culture, case, and sort rules used in the comparison. - - The string to compare to this instance. - One of the enumeration values that specifies how the strings will be compared. - true if the value of the parameter is the same as this instance; otherwise, false. - - - - Converts the as a . - - The instance. - - - - Converts the as a Dictionary<string, object>. - - The instance. - - - - Converts the as an array. - - The instance. - - - - Converts the as an array. - - The instance. - - - - Converts the as a array. - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as an . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Converts the as a . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from Dictionary<string, object>. - - The value from which will be created a new instance of the . - - - - Creates a new instance from array. - - The value from which will be created a new instance of the . - - - - Creates a new instance from array. - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Indicate whether two are not equal. - - The first instance. - The second instance. - - - - Indicate whether two are equal. - - The first instance. - The second instance. - - - - Indicate whether and are not equal. - - The instance. - The string. - - - - Indicate whether and are equal. - - The instance. - The string. - - - - Returns an that can be bound to a data source from an object that does not implement an itself. - - - - - Returns a collection of custom attributes for this instance of a component. - - - - - Returns the class name of this instance of a component. - - - - - Returns the name of this instance of a component. - - - - - Returns a type converter for this instance of a component. - - - - - Returns the default event for this instance of a component. - - - - - Returns the default property for this instance of a component. - - - - - Returns an editor of the specified type for this instance of a component. - - A that represents the editor for this object. - - - - Returns the events for this instance of a component using the specified attribute array as a filter. - - An array of type that is used as a filter. - - - - Returns the events for this instance of a component. - - - - - Returns the properties for this instance of a component using the attribute array as a filter. - - An array of type that is used as a filter. - - - - Returns the properties for this instance of a component. - - - - - Returns an object that contains the property described by the specified property descriptor. - - A that represents the property whose owner is to be found. - - - - Gets or sets the value. - - - - - Gets a collection of string keys and values of the current . - - - Has a null value, if the property is false. - - - - - Gets or sets an attributes of the XML item (only for XML). - - - - - Gets the value associated with the specified key of the . - - The key of the value to get. - - - - Gets the value associated with the specified index of the . - - The index of the value to get. - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to array. - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to . - - - - - Gets a value that indicates whether the data type of the is equal to numeric type. - - - - - Gets a value indicating whether the current object has a value. - - - - - Gets a value indicating whether the current object has an attributes (only for xml data type). - - - - - Gets the number of elements actually contained in the . - - - - - Gets or sets the key for the current item, if the current item included into the collection. - - - Assigned automatically when parsing data of JSON, XML or query string. - root for root elements. - value for . - ____ for new collections created by the developer manually. - - - - - The parent of the current item, if the current item included into the collection. - - - - - Gets or sets a value that indicates whether the data type of the is array. - - - This affects the representation of the object as a string. For arrays in a JSON is not use the . - - - - - Gets or sets a value that indicates whether the type is unreferenced. - - - - - Represents the empty . - - - - - Gets a value indicating whether the collection is a collection of objects. - - - - - Initializes a new instance of the class. - - The request results. - - - - Initializes a new instance of the class. - - The content type of the response. - The source of the response. - - - - Initializes a new instance of the class. - - The content type of the response. - The source of the response. - The HTTP headers of the response. - The HTTP status code of the response. - - - - Parses the source to the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets or sets the HTTP status code of the output returned to the client. - - - - - Gets a value indicating whether the current request result is successful or not. - - - Successful result - is a response code from 200 to 299. - - - - - Gets or sets the content type of the response. - - - - - Gets or sets the http headers of the response. - - - - - Gets the Content-Disposition header of the response. - - - - - Gets the file name, if is file. - - - - - Gets or sets the source of the response. - - - - - Gets a value indicating the is file or not. - - - - - Gets a value indicating whether the is empty or not. - - - - - Gets or sets the processed result of the response. - - - - - Gets a value indicating the is or not. - - - - - Gets a value indicating the is or not. - - - - - Gets a value indicating the is XML or not. - - - - - Gets a value indicating the is array or not. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - Result of request to the OAuth server. - - - - Returns the . - - - - - Converts the specified string to an . - - A string containing an access token to parse. - A new instance. - - - - Converts the specified string to an . - - Type Inherited from the that should be returned. - A string containing an access token to parse. - A new instance. - - - - Indicates whether the specified value is null or an . - - The instance to test. - true if the parameter is null or is false; otherwise, false. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - The access token issued by the authorization server. - - - - - Represents the empty . - - - - - Gets a value indicating whether the is empty or not. - - - - - Represents authorization results. - - - - - Initializes a new instance of the class. - - - - - The ID of the authorization request. - - - - - OAuth version. For example: 1.0, 2.0. - - - - - Provider and custom client name. - - - - - Provider name. For example: facebook, twitter, google. - - - - - The access token which is used to query the provider. - - - - - The user profile details that is returned from the provider. - - - - - Gets a value indicating whether the authorization is successful. - - - - - Gets error info when the authorization is not successful. - - - - - Gets the user ID that is returned from the provider. - - - - - Gets the username that is returned from the provider. - - - - - Gets the access token value. - - - - - Represents the name of the client. - - - - - Initializes a new instance of the . - - The provider name. - - - - Initializes a new instance of the . - - The client name. Any string. - The provider name. - - - - Returns a new instance with a specified . - - - - - Returns a new instance with a specified and . - - - - - Converts a specified string to . - - The string to parse. - - - - Encodes a string. - - The string to encode. - - - - Decodes a string. - - The string to decode. - - - - Escapes a special characters in a string. - - The string to escape. - - - - Converts any escaped characters in the input string. - - The input string containing the value to convert. - - - - Returns a string that represents the current . - - - - - Determines whether two object instances are equal. - - The object to compare with the current instance of the . - true if the specified object is equal to the current ; otherwise, false. - - - - Determines whether two object instances are equal. - - The instance of to compare with the current instance of the . - true if the specified instance is equal to the current ; otherwise, false. - - - - Serves as a hash function for a particular type. - - A hash code for the current . - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Indicate whether two are not equal. - - The first instance. - The second instance. - - - - Indicate whether two are equal. - - The first instance. - The second instance. - - - - Gets the client name. - - - - - Gets the provider name. - - - - - Gets a md5 hash code for the current instance of the . - - - - - OAuth client for Google. - - -

Register and Configure a Google Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Google Developers Console and Create Project. - - Create new project button - - Enter the project name and click the Create. - - Create new project form - - - Click to the Credential menu in the APIs & OAuth. - - - Credential menu - - - For desktop application, click the Create new Client ID, select Installed application and Other. - - - Click the Create Client ID to complete. - - - Create new Client ID for desktop application - - - You will get the Client ID and Client Secret. - Use this for creating an instance of the . - - - Create new Client ID for desktop application - - - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - For web projects create another Client ID. In the form select the Web application and specify return addresses. - - Create new Client ID for web application - - - For more details, please visit Google Developers Console Help. - -
- - The following example shows how to use the in Console Applications. - For desktop applications, the user will need to manually enter authorization code. - - class Program - { - static void Main(string[] args) - { - try - { - var google = new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - // open the login page in browser - System.Diagnostics.Process.Start(google.AuthorizationUrl); - - // waiting of entering the access code - string code = ""; - while (String.IsNullOrEmpty(code)) - { - Console.WriteLine("Enter access code:"); - code = Console.ReadLine(); - } - - Console.WriteLine(); - - // set authorization code - google.AuthorizationCode = code; - // get user info - var user = google.GetUserInfo(); - Console.WriteLine("User ID: {0}", user.UserId); - Console.WriteLine("Name: {0}", user.DisplayName); - Console.WriteLine("Email: {0}", user.Email); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - Console.ReadKey(); - } - } - - - Module Module1 - - Sub Main() - Try - Dim google As New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ' open the login page in browser - System.Diagnostics.Process.Start(google.AuthorizationUrl) - - ' waiting of entering the access code - Dim code As String = "" - Do While String.IsNullOrEmpty(code) - Console.WriteLine("Enter access code:") - code = Console.ReadLine() - Loop - - ' set authorization code - google.AuthorizationCode = code - - ' get user info - Dim user As UserInfo = google.GetUserInfo() - Console.WriteLine("User ID: {0}", user.UserId) - Console.WriteLine("Name: {0}", user.DisplayName) - Console.WriteLine("Email: {0}", user.Email) - Catch ex As Exception - Console.WriteLine(ex.Message) - End Try - Console.ReadKey() - End Sub - - End Module - - Result of the program is shown in the images below. - Log in with Google - Access code - User info - In a web projects you can use the and . - The following example shows how use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-fscjqht7ou30a75gjkde1eu1brsvbqkn.apps.googleusercontent.com", - "SI5bIZkrSB5rO03YF-CdsCJC" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-fscjqht7ou30a75gjkde1eu1brsvbqkn.apps.googleusercontent.com", - "SI5bIZkrSB5rO03YF-CdsCJC" - ) - ) - End Sub - - The GoogleLoginResult method will handle authorization result. - - public ActionResult GoogleLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function GoogleLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Google. - - public ActionResult GoogleLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Google", Url.Action("GoogleLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function GoogleLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Google", Url.Action("GoogleLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the GoogleLogin method. - - @Html.ActionLink("Log in with Google", "GoogleLogin") - - - - - - - - - - - - - - - - - - - - - - -
- - - Represents base properties and method for OAuth 2.0 client. - - - For more details, please visit . - - - - - Represents base class for OAuth client classes. - - - - - Initializes a new instance of the class. - - The address for login. - The address for the access token. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - - is null or empty. - -or- - is null or empty. - -or- - is null or empty. - -or- - is null or empty. - - - - - Redirects a client to the Authorization URL. - - - Use this method only for web applications (ASP .NET). - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Gets the access token from the remote server. - - - This is method is implemented at the protocol level ( & ). - - The is null or empty. - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Gets the user details via API of the provider. - - May contain an access token, which will have to be used in obtaining information about the user. - - This is method is implemented at the client level. - - - - - Creates a shallow copy of the current object. - - The query parameters for new copy object. - The new return URL for new copy object. - A shallow copy of the current object. - - Method creates a copy of the current object, removes tokens, change the return address, query parameters and state. - Unfortunately, I made a mistake in architecture, so I had to make this method. - - - - - - Creates a shallow copy of the current object. - - A shallow copy of the current object. - - Method creates a copy of the current object, removes tokens, change the return address, query parameters and state. - Unfortunately, I made a mistake in architecture, so I had to make this method. - - - - - - Returns the specified access token or the current access token. - - May contain an access token, which will be refunded. - Indicates the need to check the parameter refresh_token in the access token. Default: false. - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - - - - Unique provider name. - - - Client classes are required to implement this property. - The provider name must be unique. - - - - public override string ProviderName - { - get - { - return "KGB"; - } - } - - - - - - Gets the endpoint of the authorization. - - - This property is implemented at the protocol level ( & ). - - - - - Gets or sets an access token. - - - - - Gets an access token value. - - - - - Gets or sets access code for access token requests. - - - - - Gets or sets unique request identifier. - For clients the value sets is automatically. - - - - - Gets or sets the application identifier. - - - - - Gets or sets the application secret key. - - - - - Gets or sets the base address for login. - - - - - Gets or sets the address for the access token. - - - - - Gets the version of the OAuth protocol. - - - - - Gets or sets return URL. - - - At this address provider will return the user authorization results. - For many providers are needed configuration of the application on the provider website. - - - - - Gets or sets additional query parameters. - - - These parameters will be transferred to the provider. - - - - - Gets or sets a value indicating whether the current client supports revoking access token. - - - - - Gets or sets a value indicating whether the current client supports refreshing access token. - - - - - Initializes a new instance of the class. - - The address for login. - The address for the access token. - The application identifier. - The application secret key. - - - - Gets the access token from the remote server. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - The scope of the access request. - - - - - The deault scope. - - - - - The separator in the scope list. - - - - - Gets or sets grant type. - - - - - Gets or sets username if is password or client_credentials. - - - - - Gets or sets password if is password or client_credentials. - - - - - Gets the endpoint of the authorization. - - - - - Initializes a new instance of the . - - The Client ID obtained from the Google Developers Console. - The Client Secret obtained from the Google Developers Console. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - In order to Google returned the refresh_token, when receiving an access token, you must specify access_type=offline. - - - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - { - Parameters = new NameValueCollection { { "access_type", "offline" } } - } - ); - - - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) With _ - { - .Parameters = New NameValueCollection() From {{"access_type", "offline"}} - } - ) - - For more details, please see Google Documentation. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Google. - - - - - Return URL. - - - - - OAuth client for Amazon. - - -

Register and Configure Amazon Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - You need to register as developer in the App Console. - - - Sign in to the App Console - - - In the App Console register new application. - - - Register new application - - - Specify one or more return URLs. Access to any other address will be denied. - - - NOTE: Amazon supports only addresses over HTTPS (excluding localhost). - - - For example: - - https://hamster.example.org/Home/ExternalLoginResult - http://localhost:59962/Home/ExternalLoginResult - http://localhost/ - - - - Allowed Return URLs - - Do not forget to save your changes. - Use application Client ID and Client Secret when creating an instance of the class. - - Allowed Return URLs - - - OAuthManager.RegisterClient - ( - new AmazonClient - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New AmazonClient _ - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ) - - - For more details, please see Amazon Developer Documentation. - -
- - The following example shows how to add the Amazon OAuth Client to ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new AmazonClient - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New AmazonClient _ - ( - "amzn1.application-oa2-client.f0ffe4edc256488dae00dcaf96d75d1b", - "764dcefe49b441c8c6244c93e5d5d04de54fda6dfdc83da9693bf346f4dc4515" - ) - ) - End Sub - - The ExternalLoginResult method will handle authorization result. - - public ActionResult ExternalLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function ExternalLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Now you can easily redirect user to login page. - - // NOTE: use httpS scheme for real websites - string authUrl = OAuthWeb.GetAuthorizationUrl("Amazon", Url.Action("ExternalLoginResult", "Home", null, null, Request.Url.Host)); - // for example, MVC redirection from Action: - // return Redirect(authUrl); - - - ' NOTE: use httpS scheme for real websites - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Amazon", Url.Action("ExternalLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - ' for example, MVC redirection from Action - ' Return Redirect(authUrl) - - Result shown in the images below. - Amazon Sign in - Amazon User Info - - - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the class. - - The client ID obtained from the App Console. - The client secret obtained from the App Console. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Amazon. - - - - - OAuth client for Microsoft Live. - - -

Register and Configure a Live Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Live Connect App Management and Create a New Application. - - Create a New Application - - Specify the application name, read terms of use and click the I accept. - - Create a New Application form - - Open the App Settings and add return URLs. You can't use localhost. - - Redirect URLs - - On the App Settings page, you can found Client ID and Client Secret. - - Use this for creating an instance of the . - - - Cleint ID and Client Secret - - - OAuthManager.RegisterClient - ( - new LiveClient - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New LiveClient _ - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ) - - - For more details, please visit to the MSDN. - -
- - The following example shows how to add the Microsoft Live OAuth Client to ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new LiveClient - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New LiveClient _ - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - ) - End Sub - - The LiveLoginResult method will handle authorization result. - - public ActionResult LiveLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function LiveLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Microsoft Live. - - public ActionResult LiveLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Live", Url.Action("LiveLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function LiveLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Live", Url.Action("LiveLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the LiveLogin method. - - @Html.ActionLink("Log in with Microsoft Live", "LiveLogin") - - Result shown in the images below. - Microsoft Live Sign in - User Info - - - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the Live Connect App Management. - The Client Secret obtained from the Live Connect App Management. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - In order to Microsoft Live returned the refresh_token, when receiving an access token, you must specify the scope wl.offline_access. - - - OAuthManager.RegisterClient - ( - new LiveClient - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) - { - Scope = "wl.offline_access" - } - ); - - - OAuthManager.RegisterClient _ - ( - New LiveClient _ - ( - "0000000040124265", - "6ViSGIbw9N59s5Ndsfz-zaeezlBt62Ep" - ) With { .Scope = "wl.offline_access" } - ) - - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Live. - - - - - OAuth client for GitHub. - - -

Register and Configure a GitHub Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - - Register a new OAuth application. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new GitHubClient - ( - "e14122695d88f5c95bce", - "cde23ec001c5180e01e865f4efb57cb0bc848c16" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New GitHubClient _ - ( - "e14122695d88f5c95bce", - "cde23ec001c5180e01e865f4efb57cb0bc848c16" - ) - ) - - - For more details, please see GitHub Development Guides. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the GitHub Applications. - The Client Secret obtained from the GitHub Applications. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: GitHub. - - - - - OAuth client for Dropbox. - - -

Register and Configure a Dropbox Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Dropbox App Console and Create app. - Choose the Dropbox API app type. - - In the application settings you can found App key and App secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new DropboxClient - ( - "0le6wsyp3y085wy", - "48afwq9yth83y7u" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New DropboxClient _ - ( - "0le6wsyp3y085wy", - "48afwq9yth83y7u" - ) - ) - - - For more details, please visit Dropbox Platform Help. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The App key obtained from the Dropbox App Console. - The App secret obtained from the Dropbox App Console. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Unique provider name: Dropbox. - - - - - OAuth client for Foursquare. - - -

Register and Configure a Foursquare Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Foursquare App and Create app. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new FoursquareClient - ( - "LHYZN1KUXN50L141QCQFNNVOYBGUE3G3FCWFZ3EEZTOZHY5Q", - "HWXYFLLSS2IUQ0H4XNCDAZEFZKIU3MZRP5G55TNBDHRPNOQT" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New FoursquareClient _ - ( - "LHYZN1KUXN50L141QCQFNNVOYBGUE3G3FCWFZ3EEZTOZHY5Q", - "HWXYFLLSS2IUQ0H4XNCDAZEFZKIU3MZRP5G55TNBDHRPNOQT" - ) - ) - - - For more details, please visit Foursquare for Developers. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the Foursquare Apps. - The Client Secret obtained from the Foursquare Apps. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Foursquare. - - - - - OAuth client for SoundCloud. - - -

Register and Configure a SoundCloud Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the SoundCloud for Developers and Register a new app. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new SoundCloudClient - ( - "42b58d31e399664a3fb8503bfcaaa9ba", - "f9d85648da59fb95ec131b40c7645c31" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New SoundCloudClient _ - ( - "42b58d31e399664a3fb8503bfcaaa9ba", - "f9d85648da59fb95ec131b40c7645c31" - ) - ) - - - For more details, please visit SoundCloud for Developers. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the SoundCloud Applications. - The Client Secret obtained from the SoundCloud Applications. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: SoundCloud. - - - - - OAuth client for SourceForge. - - -

Register a SourceForge Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Consumer ID and Consumer Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the SourceForge Authorized Applications and Register New Application. - - You can see Consumer Key and Consumer Secret, use this for creating an instance of the . - - - OAuthManager.RegisterClient - ( - new SourceForgeClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New SourceForgeClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - - - For more details, please visit Allura API. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Represents base properties and method for OAuth 1.0 client. - - - For more details, please visit . - - - - - Initializes a new instance of the class. - - The address for the request token. - The address for login. - The address for the access token. - The application identifier. - The application secret key. - The name of hashing algorithm to calculate the signature: HMAC-SHA1 (default) or PLAINTEXT. - The is null or empty. - - - - Gets base string of the signature for current request. - - For more details, please visit - - - - Gets signature for the current request. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - - - - Gets the request token from the remote server. - - - - - Gets the access token from the remote server. - - - - - Gets or sets the address for the request token. - - - - - Get the authorization parameters. - - - - - Gets the endpoint of the authorization. - - - - - Gets or sets the request token. - - - - - Initializes a new instance of the . - - The Consumer Key obtained from the SourceForge OAuth applications. - The Consumer Secret obtained from the SourceForge OAuth applications. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - Name of the user whose data should be obtained. - - - - Gets the request token from the remote server. - - - - - Gets the access token from the remote server. - - - - - Unique provider name: SourceForge. - - - - - OAuth client for Yahoo. - - -

Register and Configure a Yahoo Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Consumer ID and Consumer Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open Yahoo Developer Network and Create a Project. - - In the application settings you can found Consumer Key and Consumer Secret. - Use this for creating an instance of the class. - - Note that Yahoo! does not work with the localhost. Use only a real servers. Make sure that your application on the Yahoo! dashboard configured correctly. - Yahoo! has a pretty flimsy OAuth interface. If something is done or configured incorrectly, the work will be nothing. But in general, the client is tested and works. - - OAuthManager.RegisterClient - ( - new YahooClient - ( - "dj0yJmk9Qm1vZ3p2TmtQUm4zJmQ9WVdrOU4wbGlkWGxJTkc4bWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD0xZQ--", - "a55738627652db0acfe464de2d9be13963b0ba1f" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New YahooClient _ - ( - "dj0yJmk9Qm1vZ3p2TmtQUm4zJmQ9WVdrOU4wbGlkWGxJTkc4bWNHbzlNQS0tJnM9Y29uc3VtZXJzZWNyZXQmeD0xZQ--", - "a55738627652db0acfe464de2d9be13963b0ba1f" - ) - ) - - - For more details, please visit Yahoo Developer Network. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Consumer Key obtained from the Yahoo Developer Dashboard. - The Consumer Secret obtained from the Yahoo Developer Dashboard. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Access token must contain the user ID in the parameter xoauth_yahoo_guid. - - - - - Gets the access token from the remote server. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - (!) - To update the access token, you must specify the return address that was used in obtaining the access token. - - - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - An exception occurs if there is no authorization code. - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - Callback address that was used in obtaining the access token. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - (!) - To update the access token, you must specify the return address that was used in obtaining the access token. - - - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - An exception occurs if there is no authorization code. - - - - Unique provider name: Yahoo. - - - - - OAuth client for LinkedIn. - - -

Register and Configure a LinkedIn Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open and sigin to the LinkedIn for Developers, and Add new app. - - In the application settings you can found Api Key and Secret Key. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new LinkedInClient - ( - "75vufylz829iim", - "VOf14z4T1jie4ezS" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New LinkedInClient _ - ( - "75vufylz829iim", - "VOf14z4T1jie4ezS" - ) - ) - - - For more details, please visit LinkedIn for Developers. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Api Key obtained from the LinkedIn Dashboard. - The Secret Key obtained from the LinkedIn Dashboard. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: LinkedIn. - - - - - OAuth client for Tumblr. - - -

Register and Configure a Tumblr Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Tumblr Dashboard, and Register an application. - - In the application settings you can found Consumer Key and Consumer Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new TumblrClient - ( - "2EZbsj2oF8OAouPlDWSVnESetAchImzPLV4q0IcQH7DGKECuzJ", - "4WZ3HBDwNuz5ZDZY8qyK1qA5QFHEJY7gkPK6ooYFCN4yw6crKd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New TumblrClient _ - ( - "2EZbsj2oF8OAouPlDWSVnESetAchImzPLV4q0IcQH7DGKECuzJ", - "4WZ3HBDwNuz5ZDZY8qyK1qA5QFHEJY7gkPK6ooYFCN4yw6crKd" - ) - ) - - - For more details, please visit Tumblr API Documentation. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Consumer Key obtained from the Tumblr Dashboard. - The Consumer Secret obtained from the Tumblr Dashboard. - - - - Gets an user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Tumblr. - - - - - OAuth client for Instagram. - - -

Register and Configure a Instagram Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Register as Developer and Register new Client ID. - - In the application settings you can found Client ID and Client Key. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new InstagramClient - ( - "215a1941ebed4e4fa74e94dd84762836", - "ba53a710e1624870bc066e7a9ae38601" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New InstagramClient _ - ( - "215a1941ebed4e4fa74e94dd84762836", - "ba53a710e1624870bc066e7a9ae38601" - ) - ) - - - For more details, please visit Instagram Developer Documentation. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the Instagram Manage Clients. - The Client Secret obtained from the Instagram Manage Clients. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Instagram. - - - - - OAuth client for CodeProject. - - -

Register and Configure a CodeProject Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - - Register a new client. - - In the application settings you can found Client ID and Client Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new CodeProjectClient - ( - "92mWWELc2DjcL-6tu7L1Py6yllleqSCt", - "YJXrk_Vzz4Ps02GqmaUY-aSLucxh4kfLq6oq0CtiukPfvbzb9yQG69NeDr2yiV9M" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New CodeProjectClient _ - ( - "92mWWELc2DjcL-6tu7L1Py6yllleqSCt", - "YJXrk_Vzz4Ps02GqmaUY-aSLucxh4kfLq6oq0CtiukPfvbzb9yQG69NeDr2yiV9M" - ) - ) - - - For more details, please see CodeProject API Documentation. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID obtained from the CodeProject Web API Clients. - The Client Secret obtained from the CodeProject Web API Clients. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: CodeProject. - - - - - OAuth client for Assembla. - - -

Register and Configure an Assembla Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - - Register a new OAuth application. - - In the application settings you can found Application ID and Application Secret. - Use this for creating an instance of the class. - - - OAuthManager.RegisterClient - ( - new AssemblaClient - ( - "bOS4QkXnmr5jhdacwqjQXA", - "701ee6dedf74fc4ad75bfa7476666a2f" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New AssemblaClient _ - ( - "bOS4QkXnmr5jhdacwqjQXA", - "701ee6dedf74fc4ad75bfa7476666a2f" - ) - ) - - - For more details, please visit Assembla API Documentation Site. - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Application ID obtained from the Assembla Applications Manager. - The Application Secret obtained from the Assembla Applications Manager. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - - - Unique provider name: Assembla. - - - - - The list of access token types. - - - - - Bearer - - - - - OAuth - - - - - The list of authorization type. - - - - - Basic - - - - - Bearer - - - - - Digest - - - - - OAuth - - - - - The list of the types a HTTP parameters. - - - - - Unformed parameter. - - - - - Parameter of the query string. - - - - - Parameter of the form. - - - - - File. - - - - - Body of the request. - - - - - Very sexy list. - - - - - No sex. - - :o) - - - - Male. - - - - - Female. - - - - - Programmer. - - - - - Deep Thought. - - - - - The list of url encding methods. - - - - - Without encoding. - - - - - for POST requests when a conetent-type is x-www-form-urlencoded. - And for other requests. - - - - - x-www-form-urlencoded (spaces encoded as plus (+) signs). - - - - - RFC 3986 (spaces encoded as %20). - - - - - Represents the access token exception. - - - - - The exception that is thrown when an error occurs while accessing the network. - - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The content type of the server request result. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The content type of the server request result. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - The HTTP headers of the output. - The HTTP status code of the output. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Instance of the . - - - - - Gets the HTTP status code of the output returned to the client. - - - - - Gets the content type of the response. - - - - - Gets the http headers of the response. - - - - - Initializes a new instance of the class with a specified message. - - The error message that explains the reason for this exception. - - - - The exception that is thrown when server of API returns error. - - - - - Initializes a new instance of the class with a specified and the exception that is the cause of this exception. - - The result of the request. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class with a specified and error message. - - The result of the request. - The error message that explains the reason for this exception. - - - - Initializes a new instance of the class with a specified error message. - - The error message that explains the reason for this exception. - - - - Initializes a new instance of the class with a specified error message and the exception that is the cause of this exception. - - The error message that explains the reason for this exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - The content type of the server request result. - - - - Initializes a new instance of the class with a specified server request result, content type and the exception that is the cause of this exception. - - The result of the request. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - The content type of the server request result. - - - - Initializes a new instance of the class with a specified server request result, content type and a error message. - - The result of the request. - The error message that explains the reason for this exception. - The content type of the server request result. - - - - Initializes a new instance of the class with a specified server request result, content type and a error message. - - The result of the request. - The error message that explains the reason for this exception. - The content type of the server request result. - - - - OAuth client for Facebook. - - -

Register and Configure a Facebook Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- - You need to register as developer. - - Open the Facebook Developers and Create a New App. - - Create new application menu - - Specify the application name and click the Create App. - - Create new application form - - - In the application dashboard you can found App ID and App Secret, this is Client ID and Client Secret. - Use this for creating an instance of the class. - - - App ID and App Secret - - - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - You can use the App ID and App Secret for desktop, mobile and web projects. -

The application availability

- - To manage the status of the application, you must provide contact information. - - - Enter a contact email on the Settings page. - - - Contact Email - - - And now, you can change availability status of the application on the Status & Review page. - - - Make App Public - -

Configure application for web projects

- For web projects, configure return URLs. - - Open the application Settings and click Advanced tab. - - - Advanced tab - - - You must add the return URLs to the Valid OAuth redirect URIs field of the Security section. - - Do not forget to save your changes. - NOTE: If the application will be used for web and desktop, then also add URL: https://www.facebook.com/connect/login_success.html. - NOTE: Enable Client OAuth Login if it's disabled. - - Valid OAuth redirect URIs - - - For more details, please see Facebook Developer Documentation. - -
- - The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Insert a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // facebook client registration - OAuthManager.RegisterClient - ( - new FacebookClient - ( - // app id - "1435890426686808", - // app secret - "c6057dfae399beee9e8dc46a4182e8fd" - ) - { - // display=popup - to open a popup window - Parameters = new NameValueCollection { { "display", "popup" } } - } - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' facebook client registration - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) With _ - { - .Parameters = New NameValueCollection() From {{"display", "popup"}} - } - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Insert a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("facebook")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("facebook")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - - Result of the program is shown in the images below. - Log in with Facebook - Facebook User Info - - - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The App ID obtained from the Facebook Developers. - The App Secret obtained from the Facebook Developers. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - For more details, please see User method in Guide of Facebook Graph API. - - - - Returns an instance of the class, containing information about the user. - - - - - Sends a request to revoke the access token. - - May contain an access token, which should be revoked. - - Provider does not support revoking the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - - - - - Unique provider name: Facebook. - - - - - Return URL. - - - - - OAuth client for Odnoklassniki. - - - Odnoklassniki is a social network service for classmates and old friends. It is popular in Russia and CIS. -

Register and Configure a Odnoklassniki Site

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open My Games page and click My Uploaded Games. - - My Games in the footer menu - - - My Uploaded Games - - Click Add App. - - Add App button - - Enter the Title, Shortname, Description, Image link and App link. Select Application type (External type) and Permission. - - - (!) - - It is important to provide a link to the application (App link).
- You must use this link as the return URL. Even for desktop applications.
- You can use localhost for desktop applications.
- It is important to specify the type of application: External. -
-
-
- - App form - - In your email box you will find email message with the Client ID, Client Secret and Public key. - - Email message - - - Use this for creating an instance of the . - - - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ) - - - For more details, please visit to the Odnoklassniki API Documentation. - -
- -

Windows Forms

- The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Add a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // odnoklassniki client registration - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - // application ID - "1094959360", - // sectet key - "E45991423E8C5AE249B44E84", - // public key - "CBACMEECEBABABABA" - ) { ReturnUrl = "http://localhost" } // return url - it's important - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' odnoklassniki client registration - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) With { .ReturnUrl = "http://localhost" } - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Odnoklassniki")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Odnoklassniki")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - -

ASP .NET MVC

- The following example shows how to use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - // application ID - "1094959360", - // sectet key - "E45991423E8C5AE249B44E84", - // public key - "CBACMEECEBABABABA" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ) - End Sub - - The OdnoklassnikiLoginResult method will handle authorization result. - - public ActionResult OdnoklassnikiLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function OdnoklassnikiLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Odnoklassniki. - - public ActionResult OdnoklassnikiLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Odnoklassniki", Url.Action("OdnoklassnikiLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function OdnoklassnikiLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Odnoklassniki", Url.Action("OdnoklassnikiLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the OdnoklassnikiLogin method. - - @Html.ActionLink("Log in with Odnoklassniki", "OdnoklassnikiLogin") - -

ASP .NET WebForms

- The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new OdnoklassnikiClient - ( - // application ID - "1094959360", - // sectet key - "E45991423E8C5AE249B44E84", - // public key - "CBACMEECEBABABABA" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New OdnoklassnikiClient _ - ( - "1094959360", - "E45991423E8C5AE249B44E84", - "CBACMEECEBABABABA" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - Response.Write(String.Format("Email: {0}", user.Email)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Response.Write(String.Format("Email: {0}", user.Email)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkOdnoklassniki" runat="server" - Text="Log in with Odnoklassniki" onclick="lnkOdnoklassniki_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkOdnoklassniki_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Odnoklassniki", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkOdnoklassniki_Click(sender As Object, e As EventArgs) Handles lnkOdnoklassniki.Click - OAuthWeb.RedirectToAuthorization("Odnoklassniki", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID. - The Client Secret. - The Public Key. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - - Unique provider name: Odnoklassniki. - - - - - Public Key for access to API. - - - - - Represents a method that is called for parsing item of the API data. - - The instance to parse. - - - - References a method to be called when a corresponding asynchronous web request completes. - - The result of the asynchronous web request. - - - - Represents the error results of the query. - - - - - Initializes a new instance of the class. - - The request results. - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets a value indicating whether the current request result is successful or not. - - Always has the value false. - - - - The exception that is thrown when a resource owner or authorization server denied the request. - - - - - The exception that is thrown when a user fails to login. - - - - - Initializes a new instance of the class with a specified error message. - - The error message that explains the reason for this exception. - - - - Initializes a new instance of the class with a specified error message and the exception that is the cause of this exception. - - The error message that explains the reason for this exception. - - - - The exception that is thrown when trying to access an unregistered OAuth client. - - - Use the for OAuth clients registration. - - - The following example illustrates a situation in which the is thrown. - - string url = OAuthWeb.GetAuthorizationUrl("facebook"); - // ... - - - Dim url As String = OAuthWeb.GetAuthorizationUrl("facebook"); - ' ... - - ClientIsNotRegisteredException - To solve the problem enough to register the client. - - // facebook client registration - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - ' facebook client registration - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - Enjoy! - - string url = OAuthWeb.GetAuthorizationUrl("facebook"); - // ... - - - Dim url As String = OAuthWeb.GetAuthorizationUrl("facebook"); - ' ... - - - - - - Initializes a new instance of the class. - - - - - Represents the empty results of the query. - - - The class is used to determine sends a request to the remote server or not. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets a value indicating whether the current request result is successful or not. - - Always has the value false. - - - - The exception that is thrown when you attempt to register the already registered client. - - - - - Initializes a new instance of the class. - - The name of the provider. - - - - Initializes a new instance of the class. - - The name of the provider and client. - - - - Gets an error message. - - - - - The exception that is thrown when has more than one . - - - - - Initializes a new instance of the . - - - - - The exception that is thrown when HttpContext.Current is null (Nothing in Visual Basic). - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Initializes a new instance of the class. - - - - - The exception occurs when you try to access a provider by provider name. If the name is incorrect, or does not exist. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with a specified error message. - - The error message that explains the reason for this exception. - An object array that contains zero or more objects to format. - - - - The exception that is thrown when adding a to the and collection has one a . - - - - - Initializes a new instance of the . - - - - - Represents a HTTP authorization header. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with specific authorization type and value. - - - - - Initializes a new instance of the class from specific source. - - - - - Removes the value with the specified key from the . - - The key of the element to remove. - - true if the element is successfully found and removed; otherwise, false. - This method returns false if key is not found in the or is not collection. - - - - - Returns OAuth string of the current object for Authorization header. - - - - - Invoked before sending a web request. - - HTTP Method of the request: POST, PUT, GET or DELETE. - URL of the web request. - The value of the Content-Type HTTP header. - >Parameters of the web request. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Gets or sets authorization method. - - - - - Gets or sets parameters of the authorization. - - - - - Authorization parameters. - - - - - Sorted authorization parameters. - - - - - Gets or sets the value associated with the specified key. - - The key of the value to get or set. - - - - Implements a file to transfer in a HTTP request. - - - - - Implements a HTTP paramter. - - - - - Initializes a new instance of the class. - - The name of the parameter. - The value of the parameter. - The content-type of the parameter. - - - - Initializes a new instance of the class. - - The name of the parameter. - The value of the parameter. - The type of the parameter. - The content-type of the parameter. - - - - Returns a string that represents the current parameter. - - - - - Gets or sets parameter name. - - - - - Gets or sets parameter value. - - - - - Gets or sets Content-Type. - - - - - Gets or sets type of the parameter. - - - - - Initializes a new instance of the class. - - Content of the file. - Name of the file. - The name of the parameter. - - - - Initializes a new instance of the class. - - The name of the parameter. - The posted file. - - - - Initializes a new instance of the class. - - Content of the file. - Name of the file. - The name of the parameter. - MIME type of the file. - - - - Gets or sets the filename. - - - - - Collection of HTTP parameters. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - The collection of parameters. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Initializes a new instance of the class. - - The body of a request. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Initializes a new instance of the class. - - The body of a request. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Initializes a new instance of the class. - - The array of parameters. - - If the parameter has a value of null (Nothing for VB), it will not be added to the collection. - - - - - Adds a parameter to the end of the collection. - - The parameter to be added to the collection. - - - - Adds a parameter to the end of the collection. - - The name of parameter. - The parameter value. - - - - Adds a to the end of the collection. - - The name of the parameter. - The parameter value. - - - - Adds a to the end of the collection. - - The name of the parameter. - The value of the parameter. - The type of the parameter. - - - - Adds a to the end of the collection. - - The name of parameter. - The posted file. - - - - Adds a to the end of the collection. - - The posted file. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The Content-Type of the file. - The content of the file. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The content of the file. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The Content-Type of the file. - The file stream. - - - - Adds a to the end of the collection. - - The name of parameter. - The name of the file. - The file stream. - - - - Adds a to the end of the collection. - - The content of the request. - - - - Adds a to the end of the collection. - - The content of the request. - - - - Adds a to the end of the collection. - - The content of the request. - - - - Adds the items of the specified collection to the end of the current instance of the . - - The collection whose items should be added to the end of the current instance of the . - - - - Adds a to the end of the collection. - - The name of parameter. - The parameter value. - - - - Adds a to the end of the collection. - - The name of parameter. - The parameter value. - - - - Adds file as content to the end of the collection. - - The posted file. - - - - Adds content to the end of the collection. - - The Content-Type of the . - The content value. - - - - Inserts an element into the instance of the at the specified index. - - The zero-based index at which item should be inserted. - The to insert. - - - - Inserts the elements of a collection into the instance of the at the specified index. - - The zero-based index at which the new elements should be inserted. - The collection whose elements should be inserted into the instance of the . - - - - Removes the first occurrence of a specific parameter from the . - - The parameter to remove from the . - - true if is successfully removed; otherwise, false. - This method also returns false if was not found in the . - - - - - Removes all the elements that match the conditions defined by the specified predicate. - - The delegate that defines the conditions of the elements to remove. - The number of elements removed from the . - - - - Removes the element at the specified index of the . - - The zero-based index of the element to remove. - - - - Removes a range of elements from the . - - The zero-based starting index of the range of elements to remove. - The number of elements to remove. - - - - Removes all elements from the . - - - - - Updates status of the collection. - - - - - Checks parameters types. - - The type for checking. - - - - Returns a string query parameters encoded by default method (). - - - - - Returns a string of query parameters with a specified separator. - - The separator of query parameters. For example: & - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified encoding parameters. - - - - - Returns a string of query parameters with a specified separator and encoding parameters. - - The separator of query parameters. - The type of the encoder. - The types of parameters to be used. - - - - Copies elements of the to a new instance. - - The true value included into the results only the parameters. The default value is false - all parameters. - - - - Gets a body for the request. - - - - - Writes the parameters to the request. - - The instance of the request. - - - - Writes a file to the request. - - The name of the parameter. - The filename. - The Content-Type of the file. - The content of the file. - The output stream instance. - - - - Writes a form-data parameter to the request. - - The name of the parameter. - The value of the parameter. - The output stream instance. - - - - Writes any parameter to the request. - - The Content-Type of the . - The content value. - The instance of the output stream. - - - - The assignment operator for array of the . - - The array that will be used as the . - New instance of the . - - - - The assignment operator for the . - - The collection that will be used as the . - New instance of the . - - - - The assignment operator for the byte array. - - The byte array of the request body. - New instance of the . - - - - The assignment operator for the . - - The instance of the of the request body. - New instance of the . - - - - Gets a value indicating whether the current collection has a files. - - - - - Gets a value indicating whether the current collection has a . - - - - - Gets a boundary for a request. - - - - - Gets or sets code page for parameters encoding. - - - - - Implements a value of the HTTP paramter. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Returns an encoded string of the value. - - - - - Returns an encoded string of the value. - - - - - Returns a string that represents the current value. - - - - - Returns a byte array that represents the current value. - - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the array of the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Implements the assignment operator for the . - - The value to be assigned. - New instance of the . - - - - Gets or sets value. - - - - - Implements a request body. - - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - Initializes a new instance of the class with a specified value. - - The parameter value. - - - - The access token class for OAuth 2.0. - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Initializes a new instance of the class. - - Result of request to the OAuth server. - - - - Initializes a new instance of the class with a specified access token and refresh token. - - The access token. - The refresh token. - - - - Initializes a new instance of the class with a specified access token and refresh token. - - The access token. - The refresh token. - The token type. For example: bearer. Default: null. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Returns the . - - - - - Converts the specified string to an . - - A string containing an access token to parse. - A new instance. - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - The access token issued by the authorization server. - - - - - The lifetime in seconds of the access token. - - - - - The refresh token, which can be used to obtain new - access tokens using the same authorization grant. - - - - - The scope of the access token. - - - - - The type of the token issued. Value is case insensitive. - - - - - Represents the authorization grant type. - - - - - Using an authorization code to confirm the identity (grant type is authorization_code). - - - - - Using username and password (grant type is password). - - - - - Using basic authorization with username and password (grant type is client_credentials). - - - - - Using a token to refreshing the access token (grant type is refresh_token). - - - - - Initializes a new instance with a specified . - - The value of grant type. - - - - Returns a string that represents the current . - - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Gets or sets the value. - - - - - Gets a value indicating whether the current value is authorization_code or not. - - - - - Gets a value indicating whether the current value is password or not. - - - - - Gets a value indicating whether the current value is client_credentials or not. - - - - - Provides helpers methods for OAuth. - - - - - Unreserved characters for the method. - - - http://tools.ietf.org/html/rfc3986#page-13 - - - - - This is main helper class. - - - - - Percent encoding. - - The text to encode. - The object that specifies the encoding scheme. - - For more details, please see: - - - - - - - - - Percent encoding. - - The text to encode. - - - - Encodes a URL string using the specified encoding object. - - The text to encode. - The type of the encoder. - - - - Encodes a URL string using the specified encoding object. - - The text to encode. - The object that specifies the encoding scheme. - The type of the encoder. - - - - Encodes a string into JavaScript string. - - The string to encode. - - - - Generate timestamp for a signature (only for OAuth 1.0). - - - - The timestamp value MUST be a positive integer. Unless otherwise - specified by the server's documentation, the timestamp is expressed - in the number of seconds since January 1, 1970 00:00:00 GMT. - - For more details, please see: - - - - - Generate random key. - - - - - Compute MD5 hash. - - Value that must be processed. - - - - Converts the string value to its equivalent string representation that is encoded with base-64 digits. - - A composite format string for encoding to Base64. - An object array that contains zero or more objects to format. - The string representation, in base 64. - - - - Performs a request using a GET method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request using a POST method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for web request. - The value of the Content-Type HTTP header. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request using a PUT method. - - URL to which will be sent to the request. - Parameters to be passed to the request. - Authorization header value. - HTTP headers for the request. - The value of the Content-Type HTTP header. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request using a DELETE method. - - URL to which will be sent to the request. - Parameters to be passed to the request. - Authorization header value. - HTTP headers for the request. - Access token to be used in the request. - Returns an instance of the class, which contains the result of the request. - - Can not be used simultaneously and . Use only one of these parameters. - - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs a request. - - HTTP Method: POST (default), PUT, GET or DELETE. - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for web request. - The value of the Content-Type HTTP header. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Reads results of the web request to the string. - - instance. - - - - Performs an async request using a GET method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request using a POST method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - The value of the Content-Type HTTP header. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request using a PUT method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - The value of the Content-Type HTTP header. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request using a DELETE method. - - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - A delegate that, if provided, is called when an async request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Performs an async request. - - HTTP Method: POST (default), PUT, GET or DELETE. - URL to which will be sent to request. - Parameters to be passed to request. - Authorization header value. - HTTP headers for request. - The value of the Content-Type HTTP header. - A delegate that, if provided, is called when an async web request is completed. - Access token to be used in the request. - - Can not be used simultaneously and . Use only one of these parameters. - - Returns an instance of the class, which contains the result of the request. - - - - The exception occurs when the query parameters are specified at the same time and . - - - - - Gets the value of the specified , if the is a . - - Source of data. - The key is to be obtained. - - - - Returns a string containing a number. - - The value for processing. - - - - Gets signature for the current request. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - The authorization parameters. - - - - Gets signature for the current request. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - The authorization parameters. - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Represents a class that extends the class by adding methods for use with query parameters. - - - - - Convert the to list of the . - - The . - - - - Returns a string of query parameters without a separator. - - The . - - - - Returns a string of query parameters with a specified separator. - - The . - The separator of query parameters. For example: & - - - - Returns a string of query parameters with a specified encoding parameters. - - The . - Disables parameters encoding. - - - - Returns a string of query parameters with a specified separator and encoding parameters. - - The . - The separator of query parameters. - Disables parameters encoding. - - - - Sorts the by alphabetically and returns a new . - - The . - - - - Removes the value with the specified key from the . - - The . - The key of the element to remove. - - - - Represents the request item to OAuth server. - - - - - Initializes a new instance of the class. - - The instance of the OAuth client. - The client name. - - - - Gets name of the client. - - - - - Gets instance of the OAuth client. - - - - - Gets date and time creation of the request. - - - - - Represents helper class for sessions management of OAuth. - - - Mainly the class is intended for web projects. - But you can use some methods of the class in desktop applications together with the WebBrowser control. - - The methods , - , - and - - will not work in desktop applications. - - - -

ASP .NET WebForms

- The following example shows how to use the in ASP .NET WebForms. - To redirect the user to the login page is used the method. - Processing of the authorization results is performed by . - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkTwitter" runat="server" - Text="Log in with Twitter" onclick="lnkTwitter_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkTwitter_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Twitter", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkTwitter_Click(sender As Object, e As EventArgs) Handles lnkTwitter.Click - OAuthWeb.RedirectToAuthorization("Twitter", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - -

Windows Forms

- The following example shows how to use the in desktop applications. - Methods redirection in Windows Forms applications do not work. To get the address of the authorization is used. - To test the example, create a new Windows Forms project with two forms. Add a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // mail.ru client registration - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' mail.ru client registration - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - -
-
- - - Redirects current client to the authorization page of the specified provider. - - Provider name, through which it is necessary to authorize the current user. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider with specified parameters. - - Provider name, through which it is necessary to authorize the current user. - Additional parameters to be passed to the authorization query. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider, query parameters and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - Additional parameters to be passed to the authorization query. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Redirects current client to the authorization page of the specified provider, query parameters and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - Additional parameters to be passed to the authorization query. - - is unregistered. Use the for OAuth clients registration. - - - The exception that is thrown when you try to access methods that are designed for web projects. - - - The method will not work in desktop applications. For desktop applications you can use . - - - - - - Returns the authorization URL of the specified provider. - - Provider name, through which it is necessary to authorize the current user. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider with specified parameters. - - Provider name, through which it is necessary to authorize the current user. - Additional parameters to be passed to the authorization URL. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider and return URL. - - Provider name, through which it is necessary to authorize the current user. - The address to which the user is redirected after the authorization. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider, query parameters and return URL. - - Provider name, through which it is necessary to authorize the current user. - Additional parameters to be passed to the authorization URL. - The address to which the user is redirected after the authorization. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Returns the authorization URL of the specified provider, query parameters and return URL. - - - The provider name, through which it is necessary to authorize the current user; or the name of the registered client. - - Additional parameters to be passed to the authorization URL. - The address to which the user is redirected after the authorization. - - The exception that is thrown when you try to access methods that are designed for web projects. - - - - - Verifies the authorization results for the current URL. - - - The method will not work in desktop applications. For desktop applications you can use the overloads or . - - - Returns the verification results. - - - - - Verifies the authorization results for the specified URL. - - Address at which to perform the verification. - - Returns the verification results. - - - - - Verifies the authorization results for the specified request identifier and the code of the authorization. - - Request identifier. - The authorization code received from the provider server. - - Returns the verification results. - - - This method is intended for internal use. It is recommended to use the overload or . - - - - - Verifies the authorization results for the current URL and removes the request from memory. - - - The method will not work in desktop applications. For desktop applications you can use the overloads or . - - - Returns the verification results. - - - - - Verifies the authorization results for the specified URL, and removes the request from memory. - - Address at which to perform the verification. - - Returns the verification results. - - - - - Verifies the authorization results for the specified request identifier and the code of the authorization, and removes the request from memory. - - Request identifier. - The authorization code received from the provider server. - - Returns the verification results. - - - This method is intended for internal use. It is recommended to use the overload or . - - - - - The access token class for OAuth 1.0. - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Initializes a new instance of the class. - - Result of request to the OAuth server. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Returns the . - - - - - Converts the specified string to an . - - A string containing an access token to parse. - A new instance. - - - - Converts the to . - - The instance. - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - The access token issued by the authorization server. - - - - - The access token issued by the authorization server. - - - - - Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. - - - - - Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. - - - - - Перезаписывает свойство CurrentUICulture текущего потока для всех - обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. - - - - - Поиск локализованного ресурса типа System.Drawing.Bitmap. - - - - - Ищет локализованную строку, похожую на Aleksey Sergeevich Nemiro is a Russian developer of applications and websites, - author of articles on programming and information technology. - - Aleksey was born on October 3, 1983 in the city of Vladivostok (Primorsky Krai, Russia). - In 2009, Aleksey migrated to the city of Yoshkar-Ola (Mari El, Russia). - - Started programming in 1998 on the G-Basic and QBasic. - - At various times worked with programming languages and technologies: - Visaul Basic, Delphi, C, Visual C++, Java, PHP, ASP VBScript and JScript [остаток строки не уместился]";. - - - - - Represents authorization parameters for OAuth 1.0. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with specific value. - - - - - Updates the nonce and the timestamp. - - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Gets base string of the signature for current request (OAuth 1.0). - - For more details, please visit - - - - Creates a new instance from . - - The value from which will be created a new instance of the . - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The token secret. - The query parameters. - The application secret key obtained from the provider website. - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The query parameters. - - - - Sets signature. - - The HTTP method: GET or POST. Default is POST. - The request URI. - The query parameters. - - - - Gets or sets the consumer key. - - - - - Gets or sets the consumer secret. - - - - - Gets or sets the token. - - - - - Gets or sets the secret token. - - - - - Gets or sets the signature method. - - - - - Gets or sets the nonce. - - - - - Gets or sets the timestamp. - - - - - Gets or sets the version of the OAuth. - - - - - Gets or sets the signature. - - - - - Gets or sets the callback address. - - - - - Gets or sets the verifier code. - - - - - OAuth client for Mail.Ru. - - - Mail.Ru is a popular email service, search engine, social network, photo & video hosting, blogs and another services in Russia and CIS. -

Register and Configure a Mail.Ru Site

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Unfortunately, the interface is only in Russian. - You must have a confirmed account in Mail.Ru. - Open Sites page and click Connect a New Site. - - Create a New Site button - - Accept the terms of the agreement. - - Terms - - Enter the site name, URL and click the Next button. - - Site name and URL - - Download the receiver.html file and place it in the root directory of your site. - This step can be skipped (Пропустить). - - receiver.html file - - The last step you will find the Client ID and Client Secret. - - Use this for creating an instance of the . - - - Cleint ID and Client Secret - - - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - - - For more details, please visit to the Mail.Ru API Documentation. - -
- -

Windows Forms

- The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Add a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // mail.ru client registration - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' mail.ru client registration - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("Mail.Ru")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - - Result of the program is shown in the images below. - Log in with Mail.Ru - Mail.Ru User Info -

ASP .NET MVC

- The following example shows how to use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new MailRuClient - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New MailRuClient _ - ( - "722701", - "d0622d3d9c9efc69e4ca42aa173b938a" - ) - ) - End Sub - - The MailRuLoginResult method will handle authorization result. - - public ActionResult MailRuLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - r.AppendFormat("Email: {0}", user.Email); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function MailRuLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - r.AppendLine() - r.AppendFormat("Email: {0}", user.Email) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Mail.Ru. - - public ActionResult MailRuLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("Mail.Ru", Url.Action("MailRuLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function MailRuLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("Mail.Ru", Url.Action("MailRuLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the MailRuLogin method. - - @Html.ActionLink("Log in with Mail.Ru", "MailRuLogin") - - NOTE: For proper processing, you will need to download and put on your site a receiver.html file. -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Client ID. - The Client Secret. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - Returns an instance of the class, containing information about the user. - - - The access token must contain the user ID in the parameter x_mailru_vid. - - - - - - Sends a request to refresh the access token. - - May contain an access token, which should be refreshed. - - If parameter is not specified, it will use the current access token from the same property of the current class instance. - Token must contain the refresh_token, which was received together with the access token. - - - Provider does not support refreshing the access token, or the method is not implemented. - Use the property , to check the possibility of calling this method. - - - Access token is not found or is not specified. - -or- - refresh_token value is empty. - - Error during execution of a web request. - - - - Unique provider name: Mail.Ru. - - - - - Return URL. - - - - - Represents helper class for management of OAuth clients. - - - You can use this class to register clients in your project. - - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Initializes the . - - - - - The method is called when the interval elapsed. - - Instance of the object that raised the event. - The event data. - - - - Adds the specified request to the collection. - - The unique request key. - The client name. - The client instance. - - - - Removes the request from collection. - - The unique request key to remove.. - - - - Registers the specified client in the application. - - The client instance. - is null or empty. - If you attempt to register the already registered client. - - - OAuthManager.RegisterClient - ( - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - OAuthManager.RegisterClient - ( - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - OAuthManager.RegisterClient _ - ( - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Registers the specified client in the application. - - The client instance. - The any name of the client. For example: Test, Release, Project #1, Ku!, Example.org etc. - is null or empty. - If you attempt to register the already registered client. - - - OAuthManager.RegisterClient - ( - "Test", - new GoogleClient - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Test", - new FacebookClient - ( - "00000000000000", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - "Test", - New GoogleClient _ - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Test", - New FacebookClient _ - ( - "00000000000000", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Registers the specified client in the application. (the main method) - - The client instance. - The any name of the client. For example: Test, Release, Project #1, Ku!, Example.org etc. - is null or empty. - If you attempt to register the already registered client. - - - OAuthManager.RegisterClient - ( - "Test", - new GoogleClient - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Test", - new FacebookClient - ( - "00000000000000", - "000000000000000000000000" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new GoogleClient - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ); - - OAuthManager.RegisterClient - ( - "Release", - new FacebookClient - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ); - - - OAuthManager.RegisterClient _ - ( - "Test", - New GoogleClient _ - ( - "00000000000000.apps.googleusercontent.com", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Test", - New FacebookClient _ - ( - "00000000000000", - "000000000000000000000000" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New GoogleClient _ - ( - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - ) - - OAuthManager.RegisterClient _ - ( - "Release", - New FacebookClient _ - ( - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - ) - - - - - - Registers the specified client in the application. - - The provider name. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - , or is null or empty. - Provider not found by . - - - OAuthManager.RegisterClient - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - OAuthManager.RegisterClient - ( - "facebook" - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ); - - - OAuthManager.RegisterClient _ - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - - OAuthManager.RegisterClient _ - ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - - - - - - Registers the specified client in the application. - - The provider name. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - List of scope that will be requested from the provider. Only for OAuth 2.0. - Additional parameters to be passed to the constructor of the client class. - Additional parameters that will be transferred to the provider website. - , or is null or empty. - Provider not found by . - The not suppored . - - - OAuthManager.RegisterClient - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - OAuthManager.RegisterClient - ( - "facebook" - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ); - - - OAuthManager.RegisterClient _ - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - - OAuthManager.RegisterClient _ - ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - - - - - - Registers the specified client in the application. - - The provider name. And may also contain any client name for for division into groups. - The application identifier obtained from the provider website. - The application secret key obtained from the provider website. - Additional parameters to be passed to the constructor of the client class. - List of scope that will be requested from the provider. Only for OAuth 2.0. - Additional parameters that will be transferred to the provider website. - , or is null or empty. - Provider not found by . - The not suppored . - - - OAuthManager.RegisterClient - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ); - - OAuthManager.RegisterClient - ( - "facebook" - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ); - - - OAuthManager.RegisterClient _ - ( - "google", - "1058655871432-83b9micke7cll89jfmcno5nftha3e95o.apps.googleusercontent.com", - "AeEbEGQqoKgOZb41JUVLvEJL" - ) - - OAuthManager.RegisterClient _ - ( - "facebook", - "1435890426686808", - "c6057dfae399beee9e8dc46a4182e8fd" - ) - - - You can register multiple clients to a single provider. - The following example shows how to do it. - - - var clientName = ClientName.Create("Debug", "Facebook"); - - OAuthManager.RegisterClient - ( - clientName - "000000000000000000", - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - ); - - clientName = ClientName.Create("Any name", "Facebook"); - - OAuthManager.RegisterClient - ( - clientName - "111111111111111111", - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - ); - - - Dim name As ClientName = ClientName.Create("Debug", "Facebook") - - OAuthManager.RegisterClient _ - ( - name, - "000000000000000000", - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - ) - - name As ClientName = ClientName.Create("Any name", "Facebook") - - OAuthManager.RegisterClient _ - ( - name, - "111111111111111111", - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - ) - - - - - - Checks registered provider with the specified name or not. - - The provider name or client name. - - - - Returns type of client by name. - - The provider name. - - - - Gets the list of all clients. - - - - - Gets the list of active requests. - - - - - Gets the list of registered clients. - - - - - Variants of the signature encryption. - - - - - HMAC-SHA1 - - - - - RSA-SHA1 - - - - - PLAINTEXT - - - - - Represents the signature of the request. This is a helper class to simplify debugging. - - - - - Initializes a new instance of the class. - - The name of hashing algorithm to calculate the signature: HMAC-SHA1 (default) or PLAINTEXT. - The secret key for encryption. - Base string of the signature. - - is not suppored. - - - - - Returns the of the current object. - - - - - Gets the secret key for encryption. - - - - - Gets the name of hashing algorithm to calculate the signature: HMAC-SHA1 or PLAINTEXT. - - - - - Get base string of the signature. - - - - - Gets the signature. - - - - - Represents the request token results. - - - - - Initializes a new instance of the class. - - The request result. - The address of the authorization. - The query parameters. Will be used in the formation of the authorization address. - - - - Returns the . - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Gets the OAuth token. - - - - - Gets the token secret. - - - - - The parameter is used to differentiate from previous versions of the protocol. - - - - - Gets the address of the authorization. - - - - - OAuth client for Twitter. - - -

Register and Configure a Twitter Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Consumer ID and Consumer Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the Twitter Application Management and Create a New App. - - Create a New App button - - Fill out the form and click the Create your Twitter application. - For web project, set a Callback URL. - - Create a New App form - - - Open the application page and click to the API Keys. - - - API Keys link - - - You can see API Key and API secret, this is Consumer Key and Consumer Secret. - Use this for creating an instance of the . - - - Client ID and Client Secret - - - OAuthManager.RegisterClient - ( - new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - - - For more details, please visit Twitter Developers Documentation. - -
- -

Console Applications

- The following example shows how to use the in Console Applications. - For desktop applications, the user will need to manually enter authorization code. - - class Program - { - static void Main(string[] args) - { - try - { - var twitter = new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ); - - // open the login page in browser - System.Diagnostics.Process.Start(twitter.AuthorizationUrl); - - // waiting of entering the access code - string code = ""; - while (String.IsNullOrEmpty(code)) - { - Console.WriteLine("Enter access code:"); - code = Console.ReadLine(); - } - - Console.WriteLine(); - - // set authorization code - twitter.AuthorizationCode = code; - // get user info - var user = twitter.GetUserInfo(); - Console.WriteLine("User ID: {0}", user.UserId); - Console.WriteLine("Name: {0}", user.DisplayName); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - Console.ReadKey(); - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Module Module1 - - Sub Main() - Try - Dim twitter As New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ' open the login page in browser - System.Diagnostics.Process.Start(twitter.AuthorizationUrl) - - ' waiting of entering the access code - Dim code As String = "" - Do While String.IsNullOrEmpty(code) - Console.WriteLine("Enter access code:") - code = Console.ReadLine() - Loop - - ' set authorization code - twitter.AuthorizationCode = code - - ' get user info - Dim user As UserInfo = twitter.GetUserInfo() - Console.WriteLine("User ID: {0}", user.UserId) - Console.WriteLine("Name: {0}", user.DisplayName) - Catch ex As Exception - Console.WriteLine(ex.Message) - End Try - Console.ReadKey() - End Sub - - End Module - - Result of the program is shown in the images below. - Log in with Twitter - Access code - User info -

ASP .NET WebForms

- In a web projects you can use the and . - The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new TwitterClient - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New TwitterClient _ - ( - "cXzSHLUy57C4gTBgMGRDuqQtr", - "3SSldiSb5H4XeEMOIIF4osPWxOy19jrveDcPHaWtHDQqgDYP9P" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkTwitter" runat="server" - Text="Log in with Twitter" onclick="lnkTwitter_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkTwitter_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Twitter", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkTwitter_Click(sender As Object, e As EventArgs) Handles lnkTwitter.Click - OAuthWeb.RedirectToAuthorization("Twitter", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - - NOTE: Do not forget to adjust the Callback URL in the Twitter Application Settings. -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The API Key obtained from the Twitter Application Management. - The API Secret obtained from the Twitter Application Management. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Unique provider name: Twitter. - - - - - OAuth client for VK (VKontakte). - - - VK (VKontakte) is "Russian Facebook". :-) -

Register and Configure a VKontakte Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the VK App development and click Create an Application. - - Create an Application button - - Specify the application name and type, and click the Connect Application. - - Creating an application - - Confirm by SMS. - - Confirmation - - - In the Application Settings you can found Application ID and Secure key, this is Client ID and Client Secret. - Use this for creating an instance of the class. - - NOTE: Change application status to Application ON and visible to all. - - Application settings - - - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ) - - For web projects, enable Open API, set Site address and configure Base domain in the Open API section. - - Base domains - - - For more details, please see VK App development. - -
- -

Windows Forms

- The following example shows how to use the in desktop applications. - To test the example, create a new Windows Forms project with two forms. Insert a Button to the Form1. - - public Form1() - { - InitializeComponent(); - button1.Click += new EventHandler(button1_Click); - } - - private void Form1_Load(object sender, EventArgs e) - { - // vk(ontakte) client registration - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - // application id - "4457505", - // secure secret - "wW5lFMVbsw0XwYFgCGG0" - ) - { - // display=popup - to open a popup window - Parameters = new NameValueCollection { { "display", "popup" } } - } - ); - } - - private void button1_Click(object sender, EventArgs e) - { - var frm = new Form2(); - frm.ShowDialog(); - } - - - Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - ' vk(ontakte) client registration - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) With _ - { - .Parameters = New NameValueCollection() From {{"display", "popup"}} - } - ) - End Sub - - Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click - Call New Form2().ShowDialog() - End Sub - - Add a WebBrowser to the Form2. - - public Form2() - { - InitializeComponent(); - webBrowser1.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted); - webBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("vk")); - } - - private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) - { - // waiting for results - if (e.Url.Query.IndexOf("code=") != -1 || e.Url.Fragment.IndexOf("code=") != -1 || e.Url.Query.IndexOf("oauth_verifier=") != -1) - { - // is the result, verify - var result = OAuthWeb.VerifyAuthorization(e.Url.ToString()); - if (result.IsSuccessfully) - { - // show user info - MessageBox.Show - ( - String.Format - ( - "User ID: {0}\r\nUsername: {1}\r\nDisplay Name: {2}\r\nE-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - result.UserInfo.DisplayName ?? result.UserInfo.FullName, - result.UserInfo.Email - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ); - } - else - { - // show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - this.Close(); - } - } - - - Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load - WebBrowser1.Navigate(OAuthWeb.GetAuthorizationUrl("vk")) - End Sub - - Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted - ' waiting for results - If Not e.Url.Query.IndexOf("code=") = -1 OrElse Not e.Url.Fragment.IndexOf("code=") = -1 OrElse Not e.Url.Query.IndexOf("oauth_verifier=") = -1 Then - ' is the result, verify - Dim result = OAuthWeb.VerifyAuthorization(e.Url.ToString()) - If result.IsSuccessfully Then - ' show user info - MessageBox.Show _ - ( - String.Format _ - ( - "User ID: {0}{4}Username: {1}{4}Display Name: {2}{4}E-Mail: {3}", - result.UserInfo.UserId, - result.UserInfo.UserName, - If(Not String.IsNullOrEmpty(result.UserInfo.DisplayName), result.UserInfo.DisplayName, result.UserInfo.FullName), - result.UserInfo.Email, - vbNewLine - ), - "Successfully", - MessageBoxButtons.OK, - MessageBoxIcon.Information - ) - Else - ' show error message - MessageBox.Show(result.ErrorInfo.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error) - End If - Me.Close() - End If - End Sub - - Result of the program is shown in the images below. - Log in with VK(ontakte) - VK User Info -

ASP .NET MVC

- The following example shows how to use the in ASP .NET MVC Application. - In the Application_Start event handler (Global.asax file) is registered the . - - protected void Application_Start() - { - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ); - } - - - Sub Application_Start() - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ) - End Sub - - The VkontakteLoginResult method will handle authorization result. - - public ActionResult VkontakteLoginResult() - { - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - // NOTE: For StringBuilder import the System.Text - StringBuilder r = new StringBuilder(); - r.AppendFormat("User ID: {0}\r\n", user.UserId); - r.AppendFormat("Name: {0}\r\n", user.DisplayName); - return new ContentResult { Content = r.ToString(), ContentType = "text/plain" }; - } - - return new ContentResult - { - Content = "Error: " + result.ErrorInfo.Message, - ContentType = "text/plain" - }; - } - - - Public Function VkontakteLoginResult() As ActionResult - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - ' NOTE: For StringBuilder import the System.Text - Dim r As New StringBuilder() - r.AppendFormat("User ID: {0}", user.UserId) - r.AppendLine() - r.AppendFormat("Name: {0}", user.DisplayName) - Return New ContentResult With { .Content = r.ToString(), .ContentType = "text/plain" } - End If - - Return New ContentResult With _ - { - .Content = "Error: " + result.ErrorInfo.Message, - .ContentType = "text/plain" - } - End Function - - Add action method for redirection to the Vkontakte. - - public ActionResult VkontakteLogin() - { - string authUrl = OAuthWeb.GetAuthorizationUrl("vk", Url.Action("VkontakteLoginResult", "Home", null, null, Request.Url.Host)); - return Redirect(authUrl); - } - - - Public Function VkontakteLogin() As ActionResult - Dim authUrl As String = OAuthWeb.GetAuthorizationUrl("vk", Url.Action("VkontakteLoginResult", "Home", Nothing, Nothing, Request.Url.Host)) - Return Redirect(authUrl) - End Function - - On a page add link to the VkontakteLogin method. - - @Html.ActionLink("Log in with VK(ontakte)", "VkontakteLogin") - -

ASP .NET WebForms

- The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new VkontakteClient - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New VkontakteClient _ - ( - "4457505", - "wW5lFMVbsw0XwYFgCGG0" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkVkontakte" runat="server" - Text="Log in with VK(ontakte)" onclick="lnkVkontakte_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkVkontakte_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("vk", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkVkontakte_Click(sender As Object, e As EventArgs) Handles lnkVkontakte.Click - OAuthWeb.RedirectToAuthorization("vk", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Application ID obtained from the VK App development. - The Secure Key obtained from the VK App development. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - - Unique provider name: VK. - - - - - Return URL. - - - - - OAuth client for Yandex. - - - Yandex is a popular search engine in Russia and CIS. -

Register and Configure a Yandex Application

- - - (!) - - Web Management Interface may change over time. Applications registration shown below may differ.
- If the interface is changed, you need to register the application and get Client ID and Client Secret. For web projects, configure return URLs.
- If you have any problems with this, please visit issues. If you do not find a solution to your problem, you can create a new question. -
-
-
- Open the register new application page, fill out the form and click Save. - NOTE: Russian language is available on the yandex.ru - Specify the application name and set permissions. - - To access a users profile, select Yandex.Username: Date of birth; Email address; User name, surname and gender. - This minimum permissions that are required to work. - - For web project, set a Callback URI. - NOTE: For desktop applications set Callback URI to https://oauth.yandex.ru/verification_code. - - Register new application - - - In the next step you will see an Application ID and Application password, this is Client ID and Client Secret. - Use this for creating an instance of the . - - - Client ID and Client Secret - - - OAuthManager.RegisterClient - ( - new YandexClient - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ); - - - OAuthManager.RegisterClient _ - ( - New YandexClient _ - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ) - - - For more details, please visit Yandex OAuth Documentation. - -
- -

Console Applications

- The following example shows how to use the in Console Applications. - For desktop applications, the user will need to manually enter authorization code. - - class Program - { - static void Main(string[] args) - { - try - { - var yandex = new YandexClient - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ); - - // open the login page in browser - System.Diagnostics.Process.Start(yandex.AuthorizationUrl); - - // waiting of entering the access code - string code = ""; - while (String.IsNullOrEmpty(code)) - { - Console.WriteLine("Enter access code:"); - code = Console.ReadLine(); - } - - Console.WriteLine(); - - // set authorization code - yandex.AuthorizationCode = code; - // get user info - var user = yandex.GetUserInfo(); - Console.WriteLine("User ID: {0}", user.UserId); - Console.WriteLine("E-Mail: {0}", user.Email); - Console.WriteLine("Name: {0}", user.DisplayName); - Console.WriteLine("Birthday: {0}", user.Birthday); - Console.WriteLine("Sex: {0}", user.Sex); - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - Console.ReadKey(); - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Module Module1 - - Sub Main() - Try - Dim yandex As New YandexClient _ - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ' open the login page in browser - System.Diagnostics.Process.Start(yandex.AuthorizationUrl) - - ' waiting of entering the access code - Dim code As String = "" - Do While String.IsNullOrEmpty(code) - Console.WriteLine("Enter access code:") - code = Console.ReadLine() - Loop - - ' set authorization code - yandex.AuthorizationCode = code - - ' get user info - Dim user As UserInfo = yandex.GetUserInfo() - Console.WriteLine("User ID: {0}", user.UserId) - Console.WriteLine("E-Mail: {0}", user.Email) - Console.WriteLine("Name: {0}", user.DisplayName) - Console.WriteLine("Birthday: {0}", user.Birthday) - Console.WriteLine("Sex: {0}", user.Sex) - Catch ex As Exception - Console.WriteLine(ex.Message) - End Try - Console.ReadKey() - End Sub - - End Module - - Result of the program is shown in the images below. - Log in with Yandex - Access code - User info -

ASP .NET WebForms

- In a web projects you can use the and . - The following example shows how to use the in ASP .NET WebForms. - To test the example, create a new ASP .NET WebForms (empty) project. Add Global.asax. - In the Application_Start event handler (Global.asax file) is registered the . - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.Security; - using System.Web.SessionState; - using Nemiro.OAuth; - using Nemiro.OAuth.Clients; - - namespace Test.CSharp.AspWebForms - { - public class Global : System.Web.HttpApplication - { - protected void Application_Start(object sender, EventArgs e) - { - OAuthManager.RegisterClient - ( - new YandexClient - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ); - } - } - } - - - Imports Nemiro.OAuth - Imports Nemiro.OAuth.Clients - - Public Class Global_asax - Inherits System.Web.HttpApplication - - Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) - OAuthManager.RegisterClient _ - ( - New YandexClient _ - ( - "0ee5f0bf2cd141a1b194a2b71b0332ce", - "59d76f7c09b54ad38e6b15f792da7a9a" - ) - ) - End Sub - - End Class - - Add ExternalLoginResult.aspx. - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ExternalLoginResult.aspx.cs" Inherits="Test.CSharp.AspWebForms.ExternalLoginResult" %gt; - And add the following code. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class ExternalLoginResult : System.Web.UI.Page - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Write("<pre>"); - var result = OAuthWeb.VerifyAuthorization(); - if (result.IsSuccessfully) - { - var user = result.UserInfo; - Response.Write(String.Format("User ID: {0}<br />", user.UserId)); - Response.Write(String.Format("E-Mail: {0}<br />", user.Email)); - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)); - } - else - { - Response.Write(result.ErrorInfo.Message); - } - Response.Write("</pre>"); - } - } - } - - - Imports Nemiro.OAuth - - Public Class ExternalLoginResult - Inherits System.Web.UI.Page - - Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load - Response.Write("<pre>") - Dim result As AuthorizationResult = OAuthWeb.VerifyAuthorization() - If result.IsSuccessfully Then - Dim user As UserInfo = result.UserInfo - Response.Write(String.Format("User ID: {0}<br />", user.UserId)) - Response.Write(String.Format("E-Mail: {0}<br />", user.Email)) - Response.Write(String.Format("Name: {0}<br />", user.DisplayName)) - Else - Response.Write(result.ErrorInfo.Message) - End If - Response.Write("</pre>") - End Sub - - End Class - - Add Default.aspx and insert one LinkButton to the page. - - <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Test.CSharp.AspWebForms.Default" %> - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - - <html xmlns="http://www.w3.org/1999/xhtml"> - <head runat="server"> - <title></title> - </head> - <body> - <form id="form1" runat="server"> - <div> - <asp:LinkButton ID="lnkYandex" runat="server" - Text="Log in with Yandex" onclick="lnkYandex_Click" /> - </div> - </form> - </body> - </html> - - Add a handler for a click on the link. - - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web; - using System.Web.UI; - using System.Web.UI.WebControls; - using Nemiro.OAuth; - - namespace Test.CSharp.AspWebForms - { - public partial class Default : System.Web.UI.Page - { - protected void lnkYandex_Click(object sender, EventArgs e) - { - OAuthWeb.RedirectToAuthorization("Yandex", new Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri); - } - } - } - - - Imports Nemiro.OAuth - - Public Class _Default - Inherits System.Web.UI.Page - - Protected Sub lnkYandex_Click(sender As Object, e As EventArgs) Handles lnkYandex.Click - OAuthWeb.RedirectToAuthorization("Yandex", New Uri(Request.Url, "ExternalLoginResult.aspx").AbsoluteUri) - End Sub - - End Class - - NOTE: Do not forget to adjust the Callback URI in the Yandex Application Settings. -
- - - - - - - - - - - - - - - - - - - - -
- - - Initializes a new instance of the . - - The Application ID. - The Application Password. - - - - Gets the user details. - - May contain an access token, which will have to be used in obtaining information about the user. - - - - Unique provider name: Yandex. - - - - - Return URL. - - - - - Implements a parameter of url. - - - - - Initializes a new instance of the class with a specified parameter name and value. - - The parameter value. - The parameter name. - - - - Represents property description of a class. - - - - - The data reader. - - - - - Initializes a new instance of the class. - - - - - Returns whether resetting an object changes its value. - - The component to test for reset capability. - - - - Gets the current value of the property on a component. - - The component with the property for which to retrieve the value. - - - - Resets the value for this property of the component to the default value. - - The component with the property value that is to be reset to the default value. - - - - Sets the value of the component to a different value. - - The component with the property value that is to be set. - The new value. - - - - Determines a value indicating whether the value of this property needs to be persisted. - - The component with the property to be examined for persistence. - - - - Gets a value indicating whether this property is read-only. - - - - - Gets the type of the property. - - - - - Gets the type of the component this property is bound to. - - - - - The for . - - - - - Initializes a new instance of the class. - - - - - Returns a collection of property descriptors for the object represented by this type descriptor. - - - - - The properties collection. - - - - - Additional type for references. - - - - - Represents the collection of the . - - - - - Initializes a new instance of the . - - - - - Initializes a new instance of the with a specified reference to parent. - - - - - Initializes a new instance of the by other an instance of the . - - - - - Adds the specified key and value to the collection. - - The key of the element to add. - The value of the element to add. - - - - Determines whether the collection contains the specified key. - - The key to locate in the collection. - is null. - - - - Removes the value with the specified key from the collection. - - The key of the element to remove. - - true if the element is successfully found and removed; otherwise, false. - - - - - Returns a string that represents the current . - - - - - Determines whether two object instances are equal. - - The object to compare with the current instance of the . - true if the specified object is equal to the current ; otherwise, false. - - - - Returns a string that represents the specified item of the . - - The item to converted. - - - - Returns a string that represents the specified instance. - - The value to converted. - - - - Adds the specified item to the . - - The item to add. - - - - Removes all items from the collection. - - - - - Determines whether the collection contains a specific value. - - The object to locate in the collection. - - - - Removes the first occurrence of a specific object from the collection. - - The object to remove from the collection. - - - - Gets the value associated with the specified key. - - The key whose value to get. - When this method returns, the value associated with the specified key, if the key is found; otherwise, the . - - - - [Is not implemented] Copies the elements of the collection to an , starting at a particular index. - - The one-dimensional that is the destination of the elements copied from collection. The must have zero-based indexing. - The zero-based index in array at which copying begins. - - - - Returns an enumerator that iterates through a collection. - - - - - Returns an enumerator that iterates through a collection. - - - - - Initializes a new instance of the . - - The with data. - The for this serialization. - - - - Populates a with the data needed to serialize the target object. - - The to populate with data. - The destination (see ) for this serialization. - - - - Returns instance from . - - The value from which will be returned the . - - - - Gets or sets items of the collection. - - - - - The reference to parent. - - - - - Gets or sets the value associated with the specified key. - - The key of the value to get or set. - - - - Gets or sets the element at the specified index. - - The zero-based index of the element to get or set. - - - - Gets a collection containing the keys in the collection. - - - - - Gets a collection containing the values in the collection. - - - - - Gets the number of elements contained in the collection. - - - - - Gets a collection containing the keys in the collection. - - - - - Gets a collection containing the values in the collection. - - - - - Gets a value indicating whether the collection is read-only. Always false. - - - - - Represents the user profile info. - - - - - Initializes a new instance of the class. - - The data source. - The mapping rules. - - - - Initializes a new instance of the class. - - The data source. - The mapping rules. - - - - Returns the or . - - - - - Gets or sets a collection containing the API request results. - - - - - Gets or sets the user ID. - - - - - Gets or sets the username. - - - - - Gets or sets the first name of the user. - - - - - Gets or sets the last name of the user. - - - - - Gets or sets the display name of the user. - - - - - Gets or sets user email address. - - - - - Gets or sets user phone. - - - - - Gets or sets user birthday. - - - - - Gets or sets user url. - - - - - Gets or sets user image url. - - - - - Gets or sets gender of the user. - - - - - Gets the first and last name. - - - - - Represents data mapping collection for API results. - - - - - Initializes a new instance of the class. - - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - The data type. - The data format. For example: "dd.MM.yyyy" for dates, or: "00" for numerics, etc. - Custom parser of the data. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - The data type. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - The data type. - The data format. For example: "dd.MM.yyyy" for dates, or: "00" for numerics, etc. - - - - Adds the specified data mapping to the collection. - - The key name in the data source. - The property name in the destination object. - Custom parser of the data. - - - - Represents data mapping item for API results. - - - - - Initializes a new instance of the class. - - - - - Gets or sets the key name in the data source. - - - - - Gets or set the property name in the destination object. - - - - - Gets or sets the data type of the property in the destination object. - - - - - Gets or sets the data format. - - - - - Gets or sets a custom parser of the data. - - - - - Implements a form parameter. - - - - - Initializes a new instance of the class with a specified parameter name and value. - - The parameter value. - The parameter name. - -
-
diff --git a/bin/net451/Nemiro.OAuth.dll b/bin/net451/Nemiro.OAuth.dll deleted file mode 100644 index f4e6cd5313cf432fa7b133c517805789f98a8519..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126976 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 4.0 + + + + + true @@ -53,6 +58,10 @@ On + + packages\Nemiro.OAuth.1.11\lib\net40\Nemiro.OAuth.dll + True + @@ -162,12 +171,7 @@ My Settings.Designer.vb - - - - {00C92C2A-D6F0-4F92-9E92-30BC891FDEE1} - Nemiro.OAuth - + 10.0 diff --git a/src/AspNetWebFormsCustomClient.VB/Default.aspx b/examples/AspNetWebFormsCustomClient.VB/Default.aspx similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/Default.aspx rename to examples/AspNetWebFormsCustomClient.VB/Default.aspx diff --git a/src/AspNetWebFormsCustomClient.VB/Default.aspx.designer.vb b/examples/AspNetWebFormsCustomClient.VB/Default.aspx.designer.vb similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/Default.aspx.designer.vb rename to examples/AspNetWebFormsCustomClient.VB/Default.aspx.designer.vb diff --git a/src/AspNetWebFormsCustomClient.VB/Default.aspx.vb b/examples/AspNetWebFormsCustomClient.VB/Default.aspx.vb similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/Default.aspx.vb rename to examples/AspNetWebFormsCustomClient.VB/Default.aspx.vb diff --git a/src/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx b/examples/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx rename to examples/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx diff --git a/src/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx.designer.vb b/examples/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx.designer.vb similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx.designer.vb rename to examples/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx.designer.vb diff --git a/src/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx.vb b/examples/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx.vb similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx.vb rename to examples/AspNetWebFormsCustomClient.VB/ExternalLoginResult.aspx.vb diff --git a/src/AspNetWebFormsCustomClient.VB/Global.asax b/examples/AspNetWebFormsCustomClient.VB/Global.asax similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/Global.asax rename to examples/AspNetWebFormsCustomClient.VB/Global.asax diff --git a/src/AspNetWebFormsCustomClient.VB/Global.asax.vb b/examples/AspNetWebFormsCustomClient.VB/Global.asax.vb similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/Global.asax.vb rename to examples/AspNetWebFormsCustomClient.VB/Global.asax.vb diff --git a/src/AspNetWebFormsCustomClient.VB/My Project/Application.Designer.vb b/examples/AspNetWebFormsCustomClient.VB/My Project/Application.Designer.vb similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/My Project/Application.Designer.vb rename to examples/AspNetWebFormsCustomClient.VB/My Project/Application.Designer.vb diff --git a/src/AspNetWebFormsCustomClient.VB/My Project/Application.myapp b/examples/AspNetWebFormsCustomClient.VB/My Project/Application.myapp similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/My Project/Application.myapp rename to examples/AspNetWebFormsCustomClient.VB/My Project/Application.myapp diff --git a/src/AspNetWebFormsCustomClient.VB/My Project/AssemblyInfo.vb b/examples/AspNetWebFormsCustomClient.VB/My Project/AssemblyInfo.vb similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/My Project/AssemblyInfo.vb rename to examples/AspNetWebFormsCustomClient.VB/My Project/AssemblyInfo.vb diff --git a/src/AspNetWebFormsCustomClient.VB/My Project/MyExtensions/MyWebExtension.vb b/examples/AspNetWebFormsCustomClient.VB/My Project/MyExtensions/MyWebExtension.vb similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/My Project/MyExtensions/MyWebExtension.vb rename to examples/AspNetWebFormsCustomClient.VB/My Project/MyExtensions/MyWebExtension.vb diff --git a/src/AspNetWebFormsCustomClient.VB/My Project/Resources.Designer.vb b/examples/AspNetWebFormsCustomClient.VB/My Project/Resources.Designer.vb similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/My Project/Resources.Designer.vb rename to examples/AspNetWebFormsCustomClient.VB/My Project/Resources.Designer.vb diff --git a/src/AspNetWebFormsCustomClient.VB/My Project/Resources.resx b/examples/AspNetWebFormsCustomClient.VB/My Project/Resources.resx similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/My Project/Resources.resx rename to examples/AspNetWebFormsCustomClient.VB/My Project/Resources.resx diff --git a/src/AspNetWebFormsCustomClient.VB/My Project/Settings.Designer.vb b/examples/AspNetWebFormsCustomClient.VB/My Project/Settings.Designer.vb similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/My Project/Settings.Designer.vb rename to examples/AspNetWebFormsCustomClient.VB/My Project/Settings.Designer.vb diff --git a/src/AspNetWebFormsCustomClient.VB/My Project/Settings.settings b/examples/AspNetWebFormsCustomClient.VB/My Project/Settings.settings similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/My Project/Settings.settings rename to examples/AspNetWebFormsCustomClient.VB/My Project/Settings.settings diff --git a/src/AspNetWebFormsCustomClient.VB/MyFacebookClient.vb b/examples/AspNetWebFormsCustomClient.VB/MyFacebookClient.vb similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/MyFacebookClient.vb rename to examples/AspNetWebFormsCustomClient.VB/MyFacebookClient.vb diff --git a/src/AspNetWebFormsCustomClient.VB/MyTwitterClient.vb b/examples/AspNetWebFormsCustomClient.VB/MyTwitterClient.vb similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/MyTwitterClient.vb rename to examples/AspNetWebFormsCustomClient.VB/MyTwitterClient.vb diff --git a/src/AspNetWebFormsCustomClient.VB/Web.Debug.config b/examples/AspNetWebFormsCustomClient.VB/Web.Debug.config similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/Web.Debug.config rename to examples/AspNetWebFormsCustomClient.VB/Web.Debug.config diff --git a/src/AspNetWebFormsCustomClient.VB/Web.Release.config b/examples/AspNetWebFormsCustomClient.VB/Web.Release.config similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/Web.Release.config rename to examples/AspNetWebFormsCustomClient.VB/Web.Release.config diff --git a/src/AspNetWebFormsCustomClient.VB/Web.config b/examples/AspNetWebFormsCustomClient.VB/Web.config similarity index 100% rename from src/AspNetWebFormsCustomClient.VB/Web.config rename to examples/AspNetWebFormsCustomClient.VB/Web.config diff --git a/src/DropBoxWebForms/DropBoxWebForms/packages.config b/examples/AspNetWebFormsCustomClient.VB/packages.config similarity index 52% rename from src/DropBoxWebForms/DropBoxWebForms/packages.config rename to examples/AspNetWebFormsCustomClient.VB/packages.config index 67937d9..7568d78 100644 --- a/src/DropBoxWebForms/DropBoxWebForms/packages.config +++ b/examples/AspNetWebFormsCustomClient.VB/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/AspNetWebFormsCustomClient/AspNetWebFormsCustomClient.csproj b/examples/AspNetWebFormsCustomClient/AspNetWebFormsCustomClient.csproj similarity index 91% rename from src/AspNetWebFormsCustomClient/AspNetWebFormsCustomClient.csproj rename to examples/AspNetWebFormsCustomClient/AspNetWebFormsCustomClient.csproj index 1cb7ba5..ec7327f 100644 --- a/src/AspNetWebFormsCustomClient/AspNetWebFormsCustomClient.csproj +++ b/examples/AspNetWebFormsCustomClient/AspNetWebFormsCustomClient.csproj @@ -20,6 +20,11 @@ 4.0 + + + + + true @@ -40,6 +45,10 @@ + + packages\Nemiro.OAuth.1.11\lib\net40\Nemiro.OAuth.dll + True + @@ -91,10 +100,7 @@ - - {00C92C2A-D6F0-4F92-9E92-30BC891FDEE1} - Nemiro.OAuth - + 10.0 diff --git a/examples/AspNetWebFormsCustomClient/AspNetWebFormsCustomClient.sln b/examples/AspNetWebFormsCustomClient/AspNetWebFormsCustomClient.sln new file mode 100644 index 0000000..230ae6d --- /dev/null +++ b/examples/AspNetWebFormsCustomClient/AspNetWebFormsCustomClient.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25123.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetWebFormsCustomClient", "AspNetWebFormsCustomClient.csproj", "{D9AB1A43-33F3-44E3-871D-C0A63B1B4F39}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D9AB1A43-33F3-44E3-871D-C0A63B1B4F39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D9AB1A43-33F3-44E3-871D-C0A63B1B4F39}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D9AB1A43-33F3-44E3-871D-C0A63B1B4F39}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D9AB1A43-33F3-44E3-871D-C0A63B1B4F39}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/AspNetWebFormsCustomClient/Default.aspx b/examples/AspNetWebFormsCustomClient/Default.aspx similarity index 100% rename from src/AspNetWebFormsCustomClient/Default.aspx rename to examples/AspNetWebFormsCustomClient/Default.aspx diff --git a/src/AspNetWebFormsCustomClient/Default.aspx.cs b/examples/AspNetWebFormsCustomClient/Default.aspx.cs similarity index 100% rename from src/AspNetWebFormsCustomClient/Default.aspx.cs rename to examples/AspNetWebFormsCustomClient/Default.aspx.cs diff --git a/src/AspNetWebFormsCustomClient/Default.aspx.designer.cs b/examples/AspNetWebFormsCustomClient/Default.aspx.designer.cs similarity index 100% rename from src/AspNetWebFormsCustomClient/Default.aspx.designer.cs rename to examples/AspNetWebFormsCustomClient/Default.aspx.designer.cs diff --git a/src/AspNetWebFormsCustomClient/ExternalLoginResult.aspx b/examples/AspNetWebFormsCustomClient/ExternalLoginResult.aspx similarity index 100% rename from src/AspNetWebFormsCustomClient/ExternalLoginResult.aspx rename to examples/AspNetWebFormsCustomClient/ExternalLoginResult.aspx diff --git a/src/AspNetWebFormsCustomClient/ExternalLoginResult.aspx.cs b/examples/AspNetWebFormsCustomClient/ExternalLoginResult.aspx.cs similarity index 100% rename from src/AspNetWebFormsCustomClient/ExternalLoginResult.aspx.cs rename to examples/AspNetWebFormsCustomClient/ExternalLoginResult.aspx.cs diff --git a/src/AspNetWebFormsCustomClient/ExternalLoginResult.aspx.designer.cs b/examples/AspNetWebFormsCustomClient/ExternalLoginResult.aspx.designer.cs similarity index 100% rename from src/AspNetWebFormsCustomClient/ExternalLoginResult.aspx.designer.cs rename to examples/AspNetWebFormsCustomClient/ExternalLoginResult.aspx.designer.cs diff --git a/src/AspNetWebFormsCustomClient/Global.asax b/examples/AspNetWebFormsCustomClient/Global.asax similarity index 100% rename from src/AspNetWebFormsCustomClient/Global.asax rename to examples/AspNetWebFormsCustomClient/Global.asax diff --git a/src/AspNetWebFormsCustomClient/Global.asax.cs b/examples/AspNetWebFormsCustomClient/Global.asax.cs similarity index 100% rename from src/AspNetWebFormsCustomClient/Global.asax.cs rename to examples/AspNetWebFormsCustomClient/Global.asax.cs diff --git a/src/AspNetWebFormsCustomClient/MyFacebookClient.cs b/examples/AspNetWebFormsCustomClient/MyFacebookClient.cs similarity index 100% rename from src/AspNetWebFormsCustomClient/MyFacebookClient.cs rename to examples/AspNetWebFormsCustomClient/MyFacebookClient.cs diff --git a/src/AspNetWebFormsCustomClient/MyTwitterClient.cs b/examples/AspNetWebFormsCustomClient/MyTwitterClient.cs similarity index 100% rename from src/AspNetWebFormsCustomClient/MyTwitterClient.cs rename to examples/AspNetWebFormsCustomClient/MyTwitterClient.cs diff --git a/src/AspNetWebFormsCustomClient/Properties/AssemblyInfo.cs b/examples/AspNetWebFormsCustomClient/Properties/AssemblyInfo.cs similarity index 100% rename from src/AspNetWebFormsCustomClient/Properties/AssemblyInfo.cs rename to examples/AspNetWebFormsCustomClient/Properties/AssemblyInfo.cs diff --git a/src/AspNetWebFormsCustomClient/Web.Debug.config b/examples/AspNetWebFormsCustomClient/Web.Debug.config similarity index 100% rename from src/AspNetWebFormsCustomClient/Web.Debug.config rename to examples/AspNetWebFormsCustomClient/Web.Debug.config diff --git a/src/AspNetWebFormsCustomClient/Web.Release.config b/examples/AspNetWebFormsCustomClient/Web.Release.config similarity index 100% rename from src/AspNetWebFormsCustomClient/Web.Release.config rename to examples/AspNetWebFormsCustomClient/Web.Release.config diff --git a/src/AspNetWebFormsCustomClient/Web.config b/examples/AspNetWebFormsCustomClient/Web.config similarity index 100% rename from src/AspNetWebFormsCustomClient/Web.config rename to examples/AspNetWebFormsCustomClient/Web.config diff --git a/src/GoogleDriveWebForms/GoogleDriveWebForms/packages.config b/examples/AspNetWebFormsCustomClient/packages.config similarity index 52% rename from src/GoogleDriveWebForms/GoogleDriveWebForms/packages.config rename to examples/AspNetWebFormsCustomClient/packages.config index 67937d9..7568d78 100644 --- a/src/GoogleDriveWebForms/GoogleDriveWebForms/packages.config +++ b/examples/AspNetWebFormsCustomClient/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/AspNetWebFormsMulticlients/AspNetWebFormsMulticlients.csproj b/examples/AspNetWebFormsMulticlients/AspNetWebFormsMulticlients.csproj similarity index 91% rename from src/AspNetWebFormsMulticlients/AspNetWebFormsMulticlients.csproj rename to examples/AspNetWebFormsMulticlients/AspNetWebFormsMulticlients.csproj index 89b673f..9ae6097 100644 --- a/src/AspNetWebFormsMulticlients/AspNetWebFormsMulticlients.csproj +++ b/examples/AspNetWebFormsMulticlients/AspNetWebFormsMulticlients.csproj @@ -20,6 +20,11 @@ 4.0 + + + + + true @@ -40,6 +45,10 @@ + + packages\Nemiro.OAuth.1.11\lib\net40\Nemiro.OAuth.dll + True + @@ -97,13 +106,8 @@ - - {00C92C2A-D6F0-4F92-9E92-30BC891FDEE1} - Nemiro.OAuth - - - - + + 10.0 diff --git a/examples/AspNetWebFormsMulticlients/AspNetWebFormsMulticlients.sln b/examples/AspNetWebFormsMulticlients/AspNetWebFormsMulticlients.sln new file mode 100644 index 0000000..4888549 --- /dev/null +++ b/examples/AspNetWebFormsMulticlients/AspNetWebFormsMulticlients.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25123.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetWebFormsMulticlients", "AspNetWebFormsMulticlients.csproj", "{E56942E3-A90A-46F2-9343-E16F042C6509}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E56942E3-A90A-46F2-9343-E16F042C6509}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E56942E3-A90A-46F2-9343-E16F042C6509}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E56942E3-A90A-46F2-9343-E16F042C6509}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E56942E3-A90A-46F2-9343-E16F042C6509}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/AspNetWebFormsMulticlients/Default.aspx b/examples/AspNetWebFormsMulticlients/Default.aspx similarity index 100% rename from src/AspNetWebFormsMulticlients/Default.aspx rename to examples/AspNetWebFormsMulticlients/Default.aspx diff --git a/src/AspNetWebFormsMulticlients/Default.aspx.cs b/examples/AspNetWebFormsMulticlients/Default.aspx.cs similarity index 100% rename from src/AspNetWebFormsMulticlients/Default.aspx.cs rename to examples/AspNetWebFormsMulticlients/Default.aspx.cs diff --git a/src/AspNetWebFormsMulticlients/Default.aspx.designer.cs b/examples/AspNetWebFormsMulticlients/Default.aspx.designer.cs similarity index 100% rename from src/AspNetWebFormsMulticlients/Default.aspx.designer.cs rename to examples/AspNetWebFormsMulticlients/Default.aspx.designer.cs diff --git a/src/AspNetWebFormsMulticlients/ExternalLoginResult.aspx b/examples/AspNetWebFormsMulticlients/ExternalLoginResult.aspx similarity index 100% rename from src/AspNetWebFormsMulticlients/ExternalLoginResult.aspx rename to examples/AspNetWebFormsMulticlients/ExternalLoginResult.aspx diff --git a/src/AspNetWebFormsMulticlients/ExternalLoginResult.aspx.cs b/examples/AspNetWebFormsMulticlients/ExternalLoginResult.aspx.cs similarity index 100% rename from src/AspNetWebFormsMulticlients/ExternalLoginResult.aspx.cs rename to examples/AspNetWebFormsMulticlients/ExternalLoginResult.aspx.cs diff --git a/src/AspNetWebFormsMulticlients/ExternalLoginResult.aspx.designer.cs b/examples/AspNetWebFormsMulticlients/ExternalLoginResult.aspx.designer.cs similarity index 100% rename from src/AspNetWebFormsMulticlients/ExternalLoginResult.aspx.designer.cs rename to examples/AspNetWebFormsMulticlients/ExternalLoginResult.aspx.designer.cs diff --git a/src/AspNetWebFormsMulticlients/Global.asax b/examples/AspNetWebFormsMulticlients/Global.asax similarity index 100% rename from src/AspNetWebFormsMulticlients/Global.asax rename to examples/AspNetWebFormsMulticlients/Global.asax diff --git a/src/AspNetWebFormsMulticlients/Global.asax.cs b/examples/AspNetWebFormsMulticlients/Global.asax.cs similarity index 100% rename from src/AspNetWebFormsMulticlients/Global.asax.cs rename to examples/AspNetWebFormsMulticlients/Global.asax.cs diff --git a/src/AspNetWebFormsMulticlients/Properties/AssemblyInfo.cs b/examples/AspNetWebFormsMulticlients/Properties/AssemblyInfo.cs similarity index 100% rename from src/AspNetWebFormsMulticlients/Properties/AssemblyInfo.cs rename to examples/AspNetWebFormsMulticlients/Properties/AssemblyInfo.cs diff --git a/src/AspNetWebFormsMulticlients/ReadMe.md b/examples/AspNetWebFormsMulticlients/README.md similarity index 100% rename from src/AspNetWebFormsMulticlients/ReadMe.md rename to examples/AspNetWebFormsMulticlients/README.md diff --git a/src/AspNetWebFormsMulticlients/RedirectToAuth.aspx b/examples/AspNetWebFormsMulticlients/RedirectToAuth.aspx similarity index 100% rename from src/AspNetWebFormsMulticlients/RedirectToAuth.aspx rename to examples/AspNetWebFormsMulticlients/RedirectToAuth.aspx diff --git a/src/AspNetWebFormsMulticlients/RedirectToAuth.aspx.cs b/examples/AspNetWebFormsMulticlients/RedirectToAuth.aspx.cs similarity index 100% rename from src/AspNetWebFormsMulticlients/RedirectToAuth.aspx.cs rename to examples/AspNetWebFormsMulticlients/RedirectToAuth.aspx.cs diff --git a/src/AspNetWebFormsMulticlients/RedirectToAuth.aspx.designer.cs b/examples/AspNetWebFormsMulticlients/RedirectToAuth.aspx.designer.cs similarity index 100% rename from src/AspNetWebFormsMulticlients/RedirectToAuth.aspx.designer.cs rename to examples/AspNetWebFormsMulticlients/RedirectToAuth.aspx.designer.cs diff --git a/src/AspNetWebFormsMulticlients/Web.Debug.config b/examples/AspNetWebFormsMulticlients/Web.Debug.config similarity index 100% rename from src/AspNetWebFormsMulticlients/Web.Debug.config rename to examples/AspNetWebFormsMulticlients/Web.Debug.config diff --git a/src/AspNetWebFormsMulticlients/Web.Release.config b/examples/AspNetWebFormsMulticlients/Web.Release.config similarity index 100% rename from src/AspNetWebFormsMulticlients/Web.Release.config rename to examples/AspNetWebFormsMulticlients/Web.Release.config diff --git a/src/AspNetWebFormsMulticlients/Web.config b/examples/AspNetWebFormsMulticlients/Web.config similarity index 100% rename from src/AspNetWebFormsMulticlients/Web.config rename to examples/AspNetWebFormsMulticlients/Web.config diff --git a/examples/AspNetWebFormsMulticlients/packages.config b/examples/AspNetWebFormsMulticlients/packages.config new file mode 100644 index 0000000..7568d78 --- /dev/null +++ b/examples/AspNetWebFormsMulticlients/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/AspWebFormsPopup/AspWebFormsPopup.csproj b/examples/AspWebFormsPopup/AspWebFormsPopup.csproj similarity index 91% rename from src/AspWebFormsPopup/AspWebFormsPopup.csproj rename to examples/AspWebFormsPopup/AspWebFormsPopup.csproj index d452521..77a703a 100644 --- a/src/AspWebFormsPopup/AspWebFormsPopup.csproj +++ b/examples/AspWebFormsPopup/AspWebFormsPopup.csproj @@ -20,6 +20,11 @@ 4.0 + + + + + true @@ -40,6 +45,10 @@ + + packages\Nemiro.OAuth.1.11\lib\net40\Nemiro.OAuth.dll + True + @@ -97,13 +106,8 @@ - - {00C92C2A-D6F0-4F92-9E92-30BC891FDEE1} - Nemiro.OAuth - - - - + + 10.0 diff --git a/examples/AspWebFormsPopup/AspWebFormsPopup.sln b/examples/AspWebFormsPopup/AspWebFormsPopup.sln new file mode 100644 index 0000000..9cd0149 --- /dev/null +++ b/examples/AspWebFormsPopup/AspWebFormsPopup.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25123.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspWebFormsPopup", "AspWebFormsPopup.csproj", "{89809A29-97A9-4C58-892B-B908B05BDEA3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {89809A29-97A9-4C58-892B-B908B05BDEA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {89809A29-97A9-4C58-892B-B908B05BDEA3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {89809A29-97A9-4C58-892B-B908B05BDEA3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {89809A29-97A9-4C58-892B-B908B05BDEA3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/AspWebFormsPopup/Default.aspx b/examples/AspWebFormsPopup/Default.aspx similarity index 100% rename from src/AspWebFormsPopup/Default.aspx rename to examples/AspWebFormsPopup/Default.aspx diff --git a/src/AspWebFormsPopup/Default.aspx.cs b/examples/AspWebFormsPopup/Default.aspx.cs similarity index 100% rename from src/AspWebFormsPopup/Default.aspx.cs rename to examples/AspWebFormsPopup/Default.aspx.cs diff --git a/src/AspWebFormsPopup/Default.aspx.designer.cs b/examples/AspWebFormsPopup/Default.aspx.designer.cs similarity index 100% rename from src/AspWebFormsPopup/Default.aspx.designer.cs rename to examples/AspWebFormsPopup/Default.aspx.designer.cs diff --git a/src/AspWebFormsPopup/ExternalLoginResult.aspx b/examples/AspWebFormsPopup/ExternalLoginResult.aspx similarity index 100% rename from src/AspWebFormsPopup/ExternalLoginResult.aspx rename to examples/AspWebFormsPopup/ExternalLoginResult.aspx diff --git a/src/AspWebFormsPopup/ExternalLoginResult.aspx.cs b/examples/AspWebFormsPopup/ExternalLoginResult.aspx.cs similarity index 100% rename from src/AspWebFormsPopup/ExternalLoginResult.aspx.cs rename to examples/AspWebFormsPopup/ExternalLoginResult.aspx.cs diff --git a/src/AspWebFormsPopup/ExternalLoginResult.aspx.designer.cs b/examples/AspWebFormsPopup/ExternalLoginResult.aspx.designer.cs similarity index 100% rename from src/AspWebFormsPopup/ExternalLoginResult.aspx.designer.cs rename to examples/AspWebFormsPopup/ExternalLoginResult.aspx.designer.cs diff --git a/src/AspWebFormsPopup/Global.asax b/examples/AspWebFormsPopup/Global.asax similarity index 100% rename from src/AspWebFormsPopup/Global.asax rename to examples/AspWebFormsPopup/Global.asax diff --git a/src/AspWebFormsPopup/Global.asax.cs b/examples/AspWebFormsPopup/Global.asax.cs similarity index 100% rename from src/AspWebFormsPopup/Global.asax.cs rename to examples/AspWebFormsPopup/Global.asax.cs diff --git a/src/AspWebFormsPopup/Properties/AssemblyInfo.cs b/examples/AspWebFormsPopup/Properties/AssemblyInfo.cs similarity index 100% rename from src/AspWebFormsPopup/Properties/AssemblyInfo.cs rename to examples/AspWebFormsPopup/Properties/AssemblyInfo.cs diff --git a/src/AspWebFormsPopup/ReadMe.md b/examples/AspWebFormsPopup/README.md similarity index 100% rename from src/AspWebFormsPopup/ReadMe.md rename to examples/AspWebFormsPopup/README.md diff --git a/src/AspWebFormsPopup/RedirectToAuth.aspx b/examples/AspWebFormsPopup/RedirectToAuth.aspx similarity index 100% rename from src/AspWebFormsPopup/RedirectToAuth.aspx rename to examples/AspWebFormsPopup/RedirectToAuth.aspx diff --git a/src/AspWebFormsPopup/RedirectToAuth.aspx.cs b/examples/AspWebFormsPopup/RedirectToAuth.aspx.cs similarity index 100% rename from src/AspWebFormsPopup/RedirectToAuth.aspx.cs rename to examples/AspWebFormsPopup/RedirectToAuth.aspx.cs diff --git a/src/AspWebFormsPopup/RedirectToAuth.aspx.designer.cs b/examples/AspWebFormsPopup/RedirectToAuth.aspx.designer.cs similarity index 100% rename from src/AspWebFormsPopup/RedirectToAuth.aspx.designer.cs rename to examples/AspWebFormsPopup/RedirectToAuth.aspx.designer.cs diff --git a/src/AspWebFormsPopup/Web.Debug.config b/examples/AspWebFormsPopup/Web.Debug.config similarity index 100% rename from src/AspWebFormsPopup/Web.Debug.config rename to examples/AspWebFormsPopup/Web.Debug.config diff --git a/src/AspWebFormsPopup/Web.Release.config b/examples/AspWebFormsPopup/Web.Release.config similarity index 100% rename from src/AspWebFormsPopup/Web.Release.config rename to examples/AspWebFormsPopup/Web.Release.config diff --git a/src/AspWebFormsPopup/Web.config b/examples/AspWebFormsPopup/Web.config similarity index 100% rename from src/AspWebFormsPopup/Web.config rename to examples/AspWebFormsPopup/Web.config diff --git a/examples/AspWebFormsPopup/packages.config b/examples/AspWebFormsPopup/packages.config new file mode 100644 index 0000000..7568d78 --- /dev/null +++ b/examples/AspWebFormsPopup/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/CodeProjectForumViewer/CodeProjectForumViewer.csproj b/examples/CodeProjectForumViewer/CodeProjectForumViewer.csproj similarity index 88% rename from src/CodeProjectForumViewer/CodeProjectForumViewer.csproj rename to examples/CodeProjectForumViewer/CodeProjectForumViewer.csproj index 326ceb1..db8f636 100644 --- a/src/CodeProjectForumViewer/CodeProjectForumViewer.csproj +++ b/examples/CodeProjectForumViewer/CodeProjectForumViewer.csproj @@ -38,9 +38,13 @@ Resources\codeproject.ico - - False - ..\packages\Nemiro.OAuth.LoginForms.1.2\lib\net40\Nemiro.OAuth.LoginForms.dll + + packages\Nemiro.OAuth.1.11\lib\net40\Nemiro.OAuth.dll + True + + + packages\Nemiro.OAuth.LoginForms.1.4.2423\lib\net40\Nemiro.OAuth.LoginForms.dll + True @@ -100,16 +104,10 @@ - + - - - {00C92C2A-D6F0-4F92-9E92-30BC891FDEE1} - Nemiro.OAuth - - - - - - False + True True - 57447 + 10160 / - - + http://localhost:57447/ False False @@ -205,4 +218,18 @@ + + + Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. + + + + + \ No newline at end of file diff --git a/examples/DemoSite/DemoOAuth.sln b/examples/DemoSite/DemoOAuth.sln new file mode 100644 index 0000000..42c75a1 --- /dev/null +++ b/examples/DemoSite/DemoOAuth.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25123.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoOAuth", "DemoOAuth.csproj", "{91CA89C3-446D-4AF1-905F-92ABD9452084}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {91CA89C3-446D-4AF1-905F-92ABD9452084}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {91CA89C3-446D-4AF1-905F-92ABD9452084}.Debug|Any CPU.Build.0 = Debug|Any CPU + {91CA89C3-446D-4AF1-905F-92ABD9452084}.Release|Any CPU.ActiveCfg = Release|Any CPU + {91CA89C3-446D-4AF1-905F-92ABD9452084}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/examples/DemoSite/Global.asax b/examples/DemoSite/Global.asax new file mode 100644 index 0000000..c7496ee --- /dev/null +++ b/examples/DemoSite/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="DemoOAuth.MvcApplication" Language="C#" %> diff --git a/src/Test.OAuthWeb/Global.asax.cs b/examples/DemoSite/Global.asax.cs similarity index 90% rename from src/Test.OAuthWeb/Global.asax.cs rename to examples/DemoSite/Global.asax.cs index 68f1ff4..ad8748f 100644 --- a/src/Test.OAuthWeb/Global.asax.cs +++ b/examples/DemoSite/Global.asax.cs @@ -12,7 +12,7 @@ using System.Threading; using System.Collections.Specialized; -namespace Test.OAuthWeb +namespace DemoOAuth { public class MvcApplication : System.Web.HttpApplication @@ -25,14 +25,7 @@ public static void RegisterGlobalFilters(GlobalFilterCollection filters) public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); - - routes.MapRoute - ( - "Api", - "Api/{action}/{method}", - new { controller = "Api", action = "Index", method = UrlParameter.Optional } - ); - + routes.MapRoute ( "Default", @@ -66,11 +59,11 @@ private void RegistrationOAuthClients() if (String.IsNullOrEmpty(clientName)) { continue; } if (String.IsNullOrEmpty(ConfigurationManager.AppSettings[String.Format("oauth:{0}:id", clientName)])) { - throw new ArgumentNullException(String.Format(Test.Resources.Strings.ClientIdIsRequired, clientName)); + throw new ArgumentNullException(String.Format(DemoOAuth.Strings.ClientIdIsRequired, clientName)); } if (String.IsNullOrEmpty(ConfigurationManager.AppSettings[String.Format("oauth:{0}:key", clientName)])) { - throw new ArgumentNullException(String.Format(Test.Resources.Strings.ClientKeyIsRequired, clientName)); + throw new ArgumentNullException(String.Format(DemoOAuth.Strings.ClientKeyIsRequired, clientName)); } // public key for odnoklassniki.ru @@ -79,7 +72,7 @@ private void RegistrationOAuthClients() { if (String.IsNullOrEmpty(ConfigurationManager.AppSettings[String.Format("oauth:{0}:publicKey", clientName)])) { - throw new ArgumentNullException(String.Format(Test.Resources.Strings.PublicKeyIsRequired, clientName)); + throw new ArgumentNullException(String.Format(DemoOAuth.Strings.PublicKeyIsRequired, clientName)); } args = new ArrayList(); args.Add(ConfigurationManager.AppSettings[String.Format("oauth:{0}:publicKey", clientName)]); diff --git a/examples/DemoSite/Images.Designer.cs b/examples/DemoSite/Images.Designer.cs new file mode 100644 index 0000000..838ab9a --- /dev/null +++ b/examples/DemoSite/Images.Designer.cs @@ -0,0 +1,283 @@ +//------------------------------------------------------------------------------ +// +// Этот код создан программой. +// Исполняемая версия:4.0.30319.42000 +// +// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае +// повторной генерации кода. +// +//------------------------------------------------------------------------------ + +namespace DemoOAuth { + using System; + + + /// + /// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. + /// + // Этот класс создан автоматически классом StronglyTypedResourceBuilder + // с помощью такого средства, как ResGen или Visual Studio. + // Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen + // с параметром /str или перестройте свой проект VS. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Images { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Images() { + } + + /// + /// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DemoOAuth.Images", typeof(Images).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Перезаписывает свойство CurrentUICulture текущего потока для всех + /// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] amazon { + get { + object obj = ResourceManager.GetObject("amazon", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] assembla { + get { + object obj = ResourceManager.GetObject("assembla", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] codeproject { + get { + object obj = ResourceManager.GetObject("codeproject", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] dropbox { + get { + object obj = ResourceManager.GetObject("dropbox", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] empty { + get { + object obj = ResourceManager.GetObject("empty", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] error { + get { + object obj = ResourceManager.GetObject("error", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] facebook { + get { + object obj = ResourceManager.GetObject("facebook", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] foursquare { + get { + object obj = ResourceManager.GetObject("foursquare", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] github { + get { + object obj = ResourceManager.GetObject("github", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] google { + get { + object obj = ResourceManager.GetObject("google", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] instagram { + get { + object obj = ResourceManager.GetObject("instagram", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] linkedin { + get { + object obj = ResourceManager.GetObject("linkedin", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] live { + get { + object obj = ResourceManager.GetObject("live", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] mailru { + get { + object obj = ResourceManager.GetObject("mailru", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] odnoklassniki { + get { + object obj = ResourceManager.GetObject("odnoklassniki", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] soundcloud { + get { + object obj = ResourceManager.GetObject("soundcloud", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] sourceforge { + get { + object obj = ResourceManager.GetObject("sourceforge", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] tumblr { + get { + object obj = ResourceManager.GetObject("tumblr", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] twitter { + get { + object obj = ResourceManager.GetObject("twitter", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] vk { + get { + object obj = ResourceManager.GetObject("vk", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] yahoo { + get { + object obj = ResourceManager.GetObject("yahoo", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Поиск локализованного ресурса типа System.Byte[]. + /// + public static byte[] yandex { + get { + object obj = ResourceManager.GetObject("yandex", resourceCulture); + return ((byte[])(obj)); + } + } + } +} diff --git a/src/Test.Resources/Images.resx b/examples/DemoSite/Images.resx similarity index 100% rename from src/Test.Resources/Images.resx rename to examples/DemoSite/Images.resx diff --git a/examples/DemoSite/Properties/AssemblyInfo.cs b/examples/DemoSite/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..1b89f88 --- /dev/null +++ b/examples/DemoSite/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Управление общими сведениями о сборке осуществляется с помощью +// набора атрибутов. Измените значения этих атрибутов для изменения сведений, +// связанных с этой сборкой. +[assembly: AssemblyTitle("DemoOAuth")] +[assembly: AssemblyDescription("http://demo-oauth.nemiro.net/")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DemoOAuth")] +[assembly: AssemblyCopyright("Copyright © Aleksey Nemiro, 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Установка значения false в параметре ComVisible делает типы в этой сборке невидимыми +// для компонентов COM. Если требуется обратиться к типу в этой сборке через +// COM, задайте атрибуту ComVisible значение true для требуемого типа. +[assembly: ComVisible(false)] + +// Следующий GUID служит для идентификации библиотеки типов typelib, если этот проект видим для COM +[assembly: Guid("91ca89c3-446d-4af1-905f-92abd9452084")] + +// Сведения о версии сборки состоят из указанных ниже четырех значений: +// +// основной номер версии; +// дополнительный номер версии; +// номер сборки; +// редакция. +// +// Можно задать все значения или принять номер сборки и номер редакции по умолчанию, +// используя "*", как показано ниже: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Test.OAuthWeb/ReadMe.md b/examples/DemoSite/README.md similarity index 100% rename from src/Test.OAuthWeb/ReadMe.md rename to examples/DemoSite/README.md diff --git a/src/Test.Resources/Resources/amazon.dat b/examples/DemoSite/Resources/amazon.dat similarity index 100% rename from src/Test.Resources/Resources/amazon.dat rename to examples/DemoSite/Resources/amazon.dat diff --git a/src/Test.Resources/Resources/amazon100.dat b/examples/DemoSite/Resources/amazon100.dat similarity index 100% rename from src/Test.Resources/Resources/amazon100.dat rename to examples/DemoSite/Resources/amazon100.dat diff --git a/src/Test.Resources/Resources/assembla.dat b/examples/DemoSite/Resources/assembla.dat similarity index 100% rename from src/Test.Resources/Resources/assembla.dat rename to examples/DemoSite/Resources/assembla.dat diff --git a/src/Test.Resources/Resources/codeproject b/examples/DemoSite/Resources/codeproject similarity index 100% rename from src/Test.Resources/Resources/codeproject rename to examples/DemoSite/Resources/codeproject diff --git a/src/Test.Resources/Resources/dropbox.dat b/examples/DemoSite/Resources/dropbox.dat similarity index 100% rename from src/Test.Resources/Resources/dropbox.dat rename to examples/DemoSite/Resources/dropbox.dat diff --git a/src/Test.Resources/Resources/empty.dat b/examples/DemoSite/Resources/empty.dat similarity index 100% rename from src/Test.Resources/Resources/empty.dat rename to examples/DemoSite/Resources/empty.dat diff --git a/src/Test.Resources/Resources/error.dat b/examples/DemoSite/Resources/error.dat similarity index 100% rename from src/Test.Resources/Resources/error.dat rename to examples/DemoSite/Resources/error.dat diff --git a/src/Test.Resources/Resources/facebook100.dat b/examples/DemoSite/Resources/facebook100.dat similarity index 100% rename from src/Test.Resources/Resources/facebook100.dat rename to examples/DemoSite/Resources/facebook100.dat diff --git a/src/Test.Resources/Resources/foursquare.dat b/examples/DemoSite/Resources/foursquare.dat similarity index 100% rename from src/Test.Resources/Resources/foursquare.dat rename to examples/DemoSite/Resources/foursquare.dat diff --git a/src/Test.Resources/Resources/github100.dat b/examples/DemoSite/Resources/github100.dat similarity index 100% rename from src/Test.Resources/Resources/github100.dat rename to examples/DemoSite/Resources/github100.dat diff --git a/src/Test.Resources/Resources/google100.dat b/examples/DemoSite/Resources/google100.dat similarity index 100% rename from src/Test.Resources/Resources/google100.dat rename to examples/DemoSite/Resources/google100.dat diff --git a/src/Test.Resources/Resources/instagram.dat b/examples/DemoSite/Resources/instagram.dat similarity index 100% rename from src/Test.Resources/Resources/instagram.dat rename to examples/DemoSite/Resources/instagram.dat diff --git a/src/Test.Resources/Resources/linkedin.dat b/examples/DemoSite/Resources/linkedin.dat similarity index 100% rename from src/Test.Resources/Resources/linkedin.dat rename to examples/DemoSite/Resources/linkedin.dat diff --git a/src/Test.Resources/Resources/live.dat b/examples/DemoSite/Resources/live.dat similarity index 100% rename from src/Test.Resources/Resources/live.dat rename to examples/DemoSite/Resources/live.dat diff --git a/src/Test.Resources/Resources/mail.ru100.dat b/examples/DemoSite/Resources/mail.ru100.dat similarity index 100% rename from src/Test.Resources/Resources/mail.ru100.dat rename to examples/DemoSite/Resources/mail.ru100.dat diff --git a/src/Test.Resources/Resources/odnoklassniki100.dat b/examples/DemoSite/Resources/odnoklassniki100.dat similarity index 100% rename from src/Test.Resources/Resources/odnoklassniki100.dat rename to examples/DemoSite/Resources/odnoklassniki100.dat diff --git a/src/Test.Resources/Resources/soundcloud.dat b/examples/DemoSite/Resources/soundcloud.dat similarity index 100% rename from src/Test.Resources/Resources/soundcloud.dat rename to examples/DemoSite/Resources/soundcloud.dat diff --git a/src/Test.Resources/Resources/sourceforge.dat b/examples/DemoSite/Resources/sourceforge.dat similarity index 100% rename from src/Test.Resources/Resources/sourceforge.dat rename to examples/DemoSite/Resources/sourceforge.dat diff --git a/src/Test.Resources/Resources/tumblr.dat b/examples/DemoSite/Resources/tumblr.dat similarity index 100% rename from src/Test.Resources/Resources/tumblr.dat rename to examples/DemoSite/Resources/tumblr.dat diff --git a/src/Test.Resources/Resources/twitter100.dat b/examples/DemoSite/Resources/twitter100.dat similarity index 100% rename from src/Test.Resources/Resources/twitter100.dat rename to examples/DemoSite/Resources/twitter100.dat diff --git a/src/Test.Resources/Resources/vk100.dat b/examples/DemoSite/Resources/vk100.dat similarity index 100% rename from src/Test.Resources/Resources/vk100.dat rename to examples/DemoSite/Resources/vk100.dat diff --git a/src/Test.Resources/Resources/yahoo.dat b/examples/DemoSite/Resources/yahoo.dat similarity index 100% rename from src/Test.Resources/Resources/yahoo.dat rename to examples/DemoSite/Resources/yahoo.dat diff --git a/src/Test.Resources/Resources/yandex100.dat b/examples/DemoSite/Resources/yandex100.dat similarity index 100% rename from src/Test.Resources/Resources/yandex100.dat rename to examples/DemoSite/Resources/yandex100.dat diff --git a/examples/DemoSite/Strings.Designer.cs b/examples/DemoSite/Strings.Designer.cs new file mode 100644 index 0000000..fb947a1 --- /dev/null +++ b/examples/DemoSite/Strings.Designer.cs @@ -0,0 +1,531 @@ +//------------------------------------------------------------------------------ +// +// Этот код создан программой. +// Исполняемая версия:4.0.30319.42000 +// +// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае +// повторной генерации кода. +// +//------------------------------------------------------------------------------ + +namespace DemoOAuth { + using System; + + + /// + /// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. + /// + // Этот класс создан автоматически классом StronglyTypedResourceBuilder + // с помощью такого средства, как ResGen или Visual Studio. + // Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen + // с параметром /str или перестройте свой проект VS. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Strings { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Strings() { + } + + /// + /// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DemoOAuth.Strings", typeof(Strings).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Перезаписывает свойство CurrentUICulture текущего потока для всех + /// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Ищет локализованную строку, похожую на Get list of music. + /// + public static string AudioList { + get { + return ResourceManager.GetString("AudioList", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Back to list of providers. + /// + public static string BackToProviders { + get { + return ResourceManager.GetString("BackToProviders", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Client ID for [{0}] not found. Please set value to the [oauth:{0}:id] parameter or remove [{0}] from [oauth:clients].. + /// + public static string ClientIdIsRequired { + get { + return ResourceManager.GetString("ClientIdIsRequired", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Cleint Secret for [{0}] not found. Please set value to the [oauth:{0}:key] parameter or remove [{0}] from [oauth:clients].. + /// + public static string ClientKeyIsRequired { + get { + return ResourceManager.GetString("ClientKeyIsRequired", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Get list of contacts. + /// + public static string ContactsList { + get { + return ResourceManager.GetString("ContactsList", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Get status. + /// + public static string CurrentStatus { + get { + return ResourceManager.GetString("CurrentStatus", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на <p>This page displays a list of registered clients.</p> + ///<p>Clients registration occurs in the <strong>Global.asax</strong> file.</p> + ///<p>Redirects to the login page you can found in the server code of the page.</p> + ///<p>The result is handled in the <strong>ExternalLoginResult</strong> page.</p> + ///<p>Try to go through the authorization procedure of any service below.</p>. + /// + public static string DefaultAbout { + get { + return ResourceManager.GetString("DefaultAbout", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на <p>If something is not working or is not working properly, please <a href="https://github.com/alekseynemiro/nemiro.oauth.dll/issues">report it to the developer</a>.</p>. + /// + public static string DemoFeedback { + get { + return ResourceManager.GetString("DemoFeedback", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на . + /// + public static string DemoHow { + get { + return ResourceManager.GetString("DemoHow", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на <p><strong>Nemiro.OAuth</strong> is a class library for authorization via <strong>OAuth</strong> protocol in <strong>.NET Framework. (VB, C#)</strong>.</p> + ///<p>The library is <a href="https://github.com/alekseynemiro/nemiro.oauth.dll">open source</a> and is licensed under the <strong>Apache License Version 2.0</strong>.</p> + ///<p> + /// To test, click on one of the icons below. Provide the required permissions for test application.<br /> + /// If everything works correctly, then after login, you will redirect to th [остаток строки не уместился]";. + /// + public static string DemoIntro { + get { + return ResourceManager.GetString("DemoIntro", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Registration and management of applications. + /// + public static string DemoProvidersTable { + get { + return ResourceManager.GetString("DemoProvidersTable", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на <p>The information in the table is current as of <strong>March 2015</strong>.</p> + ///<p>The <strong>internal name</strong> is case-insensitive.</p> + ///<p>If the provider supports the <strong>localhost</strong>, then allowed to use the <strong>HTTP</strong> protocol for <strong>localhost</strong>. + ///<strong>HTTP</strong> supports field is only for external addresses.</p> + ///. + /// + public static string DemoProviderTableInfo { + get { + return ResourceManager.GetString("DemoProviderTableInfo", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на <h2>Is it safe?</h2> + ///<p>Yes safely.</p> + ///<p> + /// After authentication and authorization, the provider server sends special authorization code to the callback page. + /// This code is a one-off and has a limited duration. + ///</p> + ///<p>The <strong>Nemiro.OAuth</strong> library uses the authorization code for convertion to an <strong>access token</strong>.</p> + ///<p>The access token is stored in the server <strong>session</strong>.</p> + ///<p>The access token is used to work with <strong>API</strong> and does not appear [остаток строки не уместился]";. + /// + public static string DemoSecurity { + get { + return ResourceManager.GetString("DemoSecurity", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на <h2>Technical information</h2> + ///<p>Latest release of the <strong>Nemiro.OAuth</strong>:</p> + ///<h3>v{1}</h3> + ///<p>Version of the <strong>Nemiro.OAuth</strong> on the current server:</p> + ///<h3>v{0}</h3> + ///<p>NOTE: The version number of the library on the server may differ from the number of the latest release.</p> + ///<ul><li><em>The first number - is the major version number. Now it is 1. In the near future the number change is not planned;</em></li> + ///<li><em>The second number - is the minor version number. Is incr [остаток строки не уместился]";. + /// + public static string DemoTechInfo { + get { + return ResourceManager.GetString("DemoTechInfo", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Nemiro.OAuth demo site. + /// + public static string DemoTitle { + get { + return ResourceManager.GetString("DemoTitle", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на <h2>Additional resources</h2> + ///<p> + /// Source code:<br /> + /// <a href="https://github.com/alekseynemiro/nemiro.oauth.dll">https://github.com/alekseynemiro/nemiro.oauth.dll</a> + ///</p> + ///<p> + ///Documentation:<br /> + /// <a href="http://oauth.nemiro.net/">http://oauth.nemiro.net/</a> + ///</p> + ///<p> + ///Ready OAuth login forms for Windows Forms projects:<br /> + ///<a href="https://github.com/alekseynemiro/Nemiro.OAuth.LoginForms">https://github.com/alekseynemiro/Nemiro.OAuth.LoginForms</a> + ///</p> + ///<p> + ///Article: «Users Authorizati [остаток строки не уместился]";. + /// + public static string DemoUsefulLinks { + get { + return ResourceManager.GetString("DemoUsefulLinks", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Download. + /// + public static string Download { + get { + return ResourceManager.GetString("Download", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Get list of friends. + /// + public static string FriendsList { + get { + return ResourceManager.GetString("FriendsList", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Get list of groups. + /// + public static string GroupsList { + get { + return ResourceManager.GetString("GroupsList", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на HTTP<br />supports. + /// + public static string HTTPSupports { + get { + return ResourceManager.GetString("HTTPSupports", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на <p>This page displays a list of registered clients.</p> + ///<p>Clients registration occurs in the <strong>Global.asax</strong> file.</p> + ///<p>Code redirects to the login page can be found in the <strong>ExternalLogin</strong> method of the <strong>HomeController</strong>.</p> + ///<p>The result is handled in the <strong>ExternalLoginResult</strong> method.</p> + ///<p>Try to go through the authorization procedure of any service below.</p>. + /// + public static string IndexAbout { + get { + return ResourceManager.GetString("IndexAbout", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Install via <a href="https://www.nuget.org/packages/Nemiro.OAuth/">NuGet</a>. + /// + public static string InstallViaNuGet { + get { + return ResourceManager.GetString("InstallViaNuGet", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Get list of interests. + /// + public static string InterestsList { + get { + return ResourceManager.GetString("InterestsList", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Internal name. + /// + public static string InternalName { + get { + return ResourceManager.GetString("InternalName", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Get list of likes. + /// + public static string LikesList { + get { + return ResourceManager.GetString("LikesList", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на localhost<br />supports. + /// + public static string LocalhostSupports { + get { + return ResourceManager.GetString("LocalhostSupports", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Multiple Url<br />supports. + /// + public static string MultipleUrlSupports { + get { + return ResourceManager.GetString("MultipleUrlSupports", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на <h1 style="color:red;text-align:center;">This site works correctly only on the demo-oauth.nemiro.net!</h1>. + /// + public static string NoForLocalhost { + get { + return ResourceManager.GetString("NoForLocalhost", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Note. + /// + public static string Note { + get { + return ResourceManager.GetString("Note", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Get list of photo albums. + /// + public static string Photoalbums { + get { + return ResourceManager.GetString("Photoalbums", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на All applications are configured on the port <strong>{0}</strong>.<br />If you have another port, the results will not shown.<br />Configure the port settings for this web project (Project =&gt; Properties =&gt; Web =&gt; Specified port), or use your own configuration applications (on sites of providers).. + /// + public static string Port59962 { + get { + return ResourceManager.GetString("Port59962", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Provider. + /// + public static string Provider { + get { + return ResourceManager.GetString("Provider", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Public Key for [{0}] not found. Please set value to the [oauth:{0}:publicKey] parameter or remove [{0}] from [oauth:clients].. + /// + public static string PublicKeyIsRequired { + get { + return ResourceManager.GetString("PublicKeyIsRequired", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Refresh token. + /// + public static string RefreshToken { + get { + return ResourceManager.GetString("RefreshToken", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Revoke token. + /// + public static string RevokeToken { + get { + return ResourceManager.GetString("RevokeToken", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на See also <a href="http://demo-oauth.nemiro.net/">http://demo-oauth.nemiro.net/</a>.. + /// + public static string SeeAlsoDemo { + get { + return ResourceManager.GetString("SeeAlsoDemo", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на The session ended. Please authorize in again to create a new session.. + /// + public static string SessionIsDead { + get { + return ResourceManager.GetString("SessionIsDead", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Show token. + /// + public static string ShowToken { + get { + return ResourceManager.GetString("ShowToken", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Get list of twits. + /// + public static string Twits { + get { + return ResourceManager.GetString("Twits", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Get list of followers. + /// + public static string TwitterFollowersList { + get { + return ResourceManager.GetString("TwitterFollowersList", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Get list of news. + /// + public static string UpdatesList { + get { + return ResourceManager.GetString("UpdatesList", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Use JavaScript links to prevent them from indexing.. + /// + public static string UseJavaScriptLinks { + get { + return ResourceManager.GetString("UseJavaScriptLinks", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на User info. + /// + public static string UserInfo { + get { + return ResourceManager.GetString("UserInfo", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на User Info. + /// + public static string UserInfoTitle { + get { + return ResourceManager.GetString("UserInfoTitle", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Warning. + /// + public static string Warning { + get { + return ResourceManager.GetString("Warning", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Get files list of Yandex.Disk. + /// + public static string YandexDiskContent { + get { + return ResourceManager.GetString("YandexDiskContent", resourceCulture); + } + } + + /// + /// Ищет локализованную строку, похожую на Summary info of Yandex.Disk. + /// + public static string YandexDiskSummary { + get { + return ResourceManager.GetString("YandexDiskSummary", resourceCulture); + } + } + } +} diff --git a/examples/DemoSite/Strings.resx b/examples/DemoSite/Strings.resx new file mode 100644 index 0000000..31783dc --- /dev/null +++ b/examples/DemoSite/Strings.resx @@ -0,0 +1,322 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Get list of music + + + Back to list of providers + + + Client ID for [{0}] not found. Please set value to the [oauth:{0}:id] parameter or remove [{0}] from [oauth:clients]. + + + Cleint Secret for [{0}] not found. Please set value to the [oauth:{0}:key] parameter or remove [{0}] from [oauth:clients]. + + + Get list of contacts + + + Get status + + + <p>This page displays a list of registered clients.</p> +<p>Clients registration occurs in the <strong>Global.asax</strong> file.</p> +<p>Redirects to the login page you can found in the server code of the page.</p> +<p>The result is handled in the <strong>ExternalLoginResult</strong> page.</p> +<p>Try to go through the authorization procedure of any service below.</p> + + + <p>If something is not working or is not working properly, please <a href="https://github.com/alekseynemiro/nemiro.oauth.dll/issues">report it to the developer</a>.</p> + + + + + + <p><strong>Nemiro.OAuth</strong> is a class library for authorization via <strong>OAuth</strong> protocol in <strong>.NET Framework. (VB, C#)</strong>.</p> +<p>The library is <a href="https://github.com/alekseynemiro/nemiro.oauth.dll">open source</a> and is licensed under the <strong>Apache License Version 2.0</strong>.</p> +<p> + To test, click on one of the icons below. Provide the required permissions for test application.<br /> + If everything works correctly, then after login, you will redirect to the <strong>demo-oauth.nemiro.net</strong>, <br /> + where you can check work with an <strong>API</strong> of the <strong>OAuth</strong> provider. +</p> + + + Registration and management of applications + + + <p>The information in the table is current as of <strong>March 2015</strong>.</p> +<p>The <strong>internal name</strong> is case-insensitive.</p> +<p>If the provider supports the <strong>localhost</strong>, then allowed to use the <strong>HTTP</strong> protocol for <strong>localhost</strong>. +<strong>HTTP</strong> supports field is only for external addresses.</p> + + + + <h2>Is it safe?</h2> +<p>Yes safely.</p> +<p> + After authentication and authorization, the provider server sends special authorization code to the callback page. + This code is a one-off and has a limited duration. +</p> +<p>The <strong>Nemiro.OAuth</strong> library uses the authorization code for convertion to an <strong>access token</strong>.</p> +<p>The access token is stored in the server <strong>session</strong>.</p> +<p>The access token is used to work with <strong>API</strong> and does not appear on the site.</p> + + + <h2>Technical information</h2> +<p>Latest release of the <strong>Nemiro.OAuth</strong>:</p> +<h3>v{1}</h3> +<p>Version of the <strong>Nemiro.OAuth</strong> on the current server:</p> +<h3>v{0}</h3> +<p>NOTE: The version number of the library on the server may differ from the number of the latest release.</p> +<ul><li><em>The first number - is the major version number. Now it is 1. In the near future the number change is not planned;</em></li> +<li><em>The second number - is the minor version number. Is incremented when only minor features or significant fixes have been added. While maintaining compatibility with previous versions.;</em></li> +<li><em>The third number - is the version of the <strong>.NET Framework</strong>;</em></li> +<li><em>The fourth number - is the revision number in local revision control system.</em></li></ul> + + + Nemiro.OAuth demo site + + + <h2>Additional resources</h2> +<p> + Source code:<br /> + <a href="https://github.com/alekseynemiro/nemiro.oauth.dll">https://github.com/alekseynemiro/nemiro.oauth.dll</a> +</p> +<p> +Documentation:<br /> + <a href="http://oauth.nemiro.net/">http://oauth.nemiro.net/</a> +</p> +<p> +Ready OAuth login forms for Windows Forms projects:<br /> +<a href="https://github.com/alekseynemiro/Nemiro.OAuth.LoginForms">https://github.com/alekseynemiro/Nemiro.OAuth.LoginForms</a> +</p> +<p> +Article: «Users Authorization through OAuth in .NET Framework»<br /> +<a href="http://www.codeproject.com/Articles/875991/Users-Authorization-through-OAuth-in-NET-Framework">http://www.codeproject.com/Articles/875991/Users-Authorization-through-OAuth-in-NET-Framework</a> +</p> +<p> +Video: «Creating a simple file manager for Dropbox»<br /> +<a href="http://www.youtube.com/watch?v=fcT-Jt8rcdY">http://www.youtube.com/watch?v=fcT-Jt8rcdY</a> +</p> +<p> + Other projects:<br /> + <a href="http://nemiro.net/">http://nemiro.net/</a> +<p> +<a href="https://stackoverflow.com/questions/ask?tags=nemiro.oauth" style="color:red">Ask a Question</a> +</p> + + + Download + + + Get list of friends + + + Get list of groups + + + HTTP<br />supports + + + <p>This page displays a list of registered clients.</p> +<p>Clients registration occurs in the <strong>Global.asax</strong> file.</p> +<p>Code redirects to the login page can be found in the <strong>ExternalLogin</strong> method of the <strong>HomeController</strong>.</p> +<p>The result is handled in the <strong>ExternalLoginResult</strong> method.</p> +<p>Try to go through the authorization procedure of any service below.</p> + + + Install via <a href="https://www.nuget.org/packages/Nemiro.OAuth/">NuGet</a> + + + Get list of interests + + + Internal name + + + Get list of likes + + + localhost<br />supports + + + Multiple Url<br />supports + + + <h1 style="color:red;text-align:center;">This site works correctly only on the demo-oauth.nemiro.net!</h1> + + + Note + + + Get list of photo albums + + + All applications are configured on the port <strong>{0}</strong>.<br />If you have another port, the results will not shown.<br />Configure the port settings for this web project (Project =&gt; Properties =&gt; Web =&gt; Specified port), or use your own configuration applications (on sites of providers). + + + Provider + + + Public Key for [{0}] not found. Please set value to the [oauth:{0}:publicKey] parameter or remove [{0}] from [oauth:clients]. + + + See also <a href="http://demo-oauth.nemiro.net/">http://demo-oauth.nemiro.net/</a>. + + + The session ended. Please authorize in again to create a new session. + + + Get list of twits + + + Get list of followers + + + Get list of news + + + Use JavaScript links to prevent them from indexing. + + + User Info + + + Warning + + + Get files list of Yandex.Disk + + + Summary info of Yandex.Disk + + + Refresh token + + + Revoke token + + + Show token + + + User info + + \ No newline at end of file diff --git a/src/Test.Resources/Strings.ru.Designer.cs b/examples/DemoSite/Strings.ru.Designer.cs similarity index 100% rename from src/Test.Resources/Strings.ru.Designer.cs rename to examples/DemoSite/Strings.ru.Designer.cs diff --git a/examples/DemoSite/Strings.ru.resx b/examples/DemoSite/Strings.ru.resx new file mode 100644 index 0000000..24359c8 --- /dev/null +++ b/examples/DemoSite/Strings.ru.resx @@ -0,0 +1,377 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Список музыки + + + Вернуться к списку поставщиков + + + Client ID для [{0}] не найден. Пожалуйста, укажите идентификатор приложения в параметре [oauth:{0}:id], либо удалите клиента [{0}] из параметра [oauth:clients] (файл web.config). + + + Cleint Secret для [{0}] не найден. Пожалуйста, укажите секретный ключ в параметре [oauth:{0}:key], либо удалите клиента [{0}] из параметра [oauth:clients] (файл web.config). + + + Список контактов + + + Текущий статус + + + <p>На этой странице выведен список всех зарегистрированных в приложении поставщиков OAuth.</p> +<p>Регистрация поставщиков производится в файле <strong>Global.asax</strong>.</p> +<p>Перенаправление на авторизацию можно найти в серверном коде этой страницы.</p> +<p>Обработка результатов авторизации производится на странице <strong>ExternalLoginResult.asxp</strong>.</p> +<p>Попробуйте пройти процедуру авторизации, нажав на любую из кнопок.</p> + + + <p>Если что-то не работает или работает неправильно, пожалуйста, <a href="https://github.com/alekseynemiro/nemiro.oauth.dll/issues">сообщите об этом разработчику</a>.</p> + + + <h2>Как работает этот сайт?</h2> + +<p>Демонстрационный сайт <strong>demo-oauth.nemiro.net</strong> имеет немного другой код, чем представленные в <a href="http://oauth.nemiro.net/">документации</a> примеры.</p> +<p>Параметры конфигурации приложений для поставщиков <strong>OAuth</strong> находятся в файле <a href="https://github.com/alekseynemiro/nemiro.oauth.dll/blob/master/src/DemoOAuth/Web.config">web.config</a> (в целях безопасности, секретные ключи были удалены из публичного файла).</p> +<p>Список поставщиков <strong>OAuth</strong>, которые нужно использовать на сайте, находится в параметре <strong>oauth:clients</strong>. Имена поставщиков записываются через запятую, без пробелов.</p> +<p> + Идентификаторы и секретные ключи приложений указываются в параметрах <strong>oauth:{имя поставщика}:id</strong> и <strong>oauth:{имя поставщика}:key</strong>.<br /> + Где <strong>{имя поставщика}</strong> - это имя поставщика <strong>OAuth</strong>, для которого предназначены указанные настройки. +</p> +<p> + Помимо этого, в файле <a href="https://github.com/alekseynemiro/nemiro.oauth.dll/blob/master/src/DemoOAuth/Web.config">web.config</a>, + в параметре <strong>oauth:{имя поставщика}:scope</strong> можно указать права доступа, которые необходимы приложению. + Список прав нужно указывать в том формате, в котором требует поставщик <strong>OAuth</strong> (см. документацию на сайте конкретного поставщика). +</p> +<p> + Инициализация поставщиков производится в методе <strong>RegistrationOAuthClients</strong> + файла <a href="https://github.com/alekseynemiro/nemiro.oauth.dll/blob/master/src/DemoOAuth/Global.asax.cs">Global.asax</a>. +</p> +<p> + Перенаправление на авторизацию осуществляется в методе <strong>ExternalLogin</strong> + контроллера <a href="https://github.com/alekseynemiro/nemiro.oauth.dll/blob/master/src/DemoOAuth/Controllers/HomeController.cs">HomeController</a>. +</p> +<p> + Обработка результатов авторизации происходит в методе <strong>ExternalLoginResult</strong>. + Полученные с внешего сервера данные заносятся в <strong>Session</strong>. +</p> +<p> + Для работы с <strong>API</strong>, для отдельных поставщиков, сделаны свои представления, которые можно найти в папке + <a href="https://github.com/alekseynemiro/nemiro.oauth.dll/tree/master/src/DemoOAuth/Views/Shared">Shared</a>. +</p> +<p> + Отправка запросов к <strong>API</strong> и обработка ответов осуществляется в контроллере + <a href="https://github.com/alekseynemiro/nemiro.oauth.dll/blob/master/src/DemoOAuth/Controllers/ApiController.cs">ApiController</a>. + Исключение составляет базовая информация о пользователе, которая получается непосредственно библиотекой <strong>Nemiro.OAuth</strong>. +</p> +<p> + Все тексты и изображения, которые выводятся на этом сайте, + находятся в отдельном <a href="https://github.com/alekseynemiro/nemiro.oauth.dll/tree/master/src/DemoOAuth">проекте-ресурсов</a>. + Исключая, конечно данные, которые были получены от <strong>API</strong>. +</p> +<p> + Вывод иконок поставщиков <strong>OAuth</strong> из ресурсов осуществляется методом <strong>Icon</strong> + контроллера <a href="https://github.com/alekseynemiro/nemiro.oauth.dll/blob/master/src/DemoOAuth/Controllers/HomeController.cs">HomeController</a>. +</p> +<p>При желании, вы можете использовать подобную реализацию в собственных проектах.</p> + + + <p>Библиотека <strong>Nemiro.OAuth</strong> предназначена для реализации авторизации по протоколу <strong>OAuth</strong> в проектах <strong>.NET Framework (VB, C#)</strong>.</p> +<p>Библиотека является бесплатной. Исходный код <a href="https://github.com/alekseynemiro/nemiro.oauth.dll">открыт</a> и предоставляется по лицензии <strong>Apache 2.0</strong>.</p> +<p> + Для проверки работы библиотеки, нажмите на одну из иконок, расположенных ниже.<br /> + Если потребуется, пройдите процедуру аутентификации на внешнем сайте.<br /> + Разрешите тестовому приложению доступ к запрашиваемым данным.<br /> + Если все работает правильно, то после авторизации на внешнем ресурсе, вы вернетесь обратно на сайт <strong>demo-oauth.nemiro.net</strong>, + где сможете проверить работу с <strong>API</strong> выбранного поставщика <strong>OAuth</strong>. +</p> + + + Регистрация и управление приложениями на сайтах поставщиков OAuth + + + <p>Информация в таблице актуальна по состоянию на <strong>март 2015 года</strong>.</p> +<p><strong>Внутреннее имя</strong> – это строковое имя, которое используется в библиотеке <strong>Nemiro.OAuth</strong>. Регистр символов не имеет значения.</p> +<p>Если поставщик поддерживает запросы с <strong>localhost</strong>, то эти запросы можно осуществлять через протокол <strong>HTTP</strong>, не зависимо от поддержки провайдером протокола <strong>HTTP</strong>.<br />Значение параметра <strong>Разрешен протокол HTTP</strong> актуально только для внешних доменов.</p> + + + + <h2>Этот сайт безопасно использовать?</h2> +<p>Да, безопасно. Ваши учетные данные известны только серверу-поставщику <strong>OAuth</strong>.</p> +<p> + После аутентификации и авторизации, поставщик передает на страницу обратного вызова специальный код авторизации. + Этот код одноразовый и, как правило, с довольно ограниченным сроком действия. + Сама страница обратного вызова всегда возвращает HTTP-код 403, чтобы полностью исключить попадание в поисковый индекс. +</p> +<p>Библиотека <strong>Nemiro.OAuth</strong> использует код авторизации для получения маркера доступа (<strong>access token</strong>).</p> +<p>Маркер доступа записывается в сессию (<strong>session</strong>) сервера и ни в каком виде не выводится на страницах сайта.</p> +<p>Маркер доступа используется для работы с <strong>API</strong> поставщиков <strong>OAuth</strong>.</p> +<p>Все запросы делаются по защищенному протоколу <strong>HTTPS</strong>.</p> +<p>В <a href="https://github.com/alekseynemiro/nemiro.oauth.dll/tree/master/src/DemoOAuth">опубликованном исходном коде</a> сайта <strong>demo-oauth.nemiro.net</strong>, параметры доступа к поставщикам <strong>OAuth</strong>, в целях безопасности, <a href="https://github.com/alekseynemiro/nemiro.oauth.dll/blob/master/src/DemoOAuth/Web.config">отсутствуют</a>.</p> +<p> + Некоторые поставщики требуют, чтобы страница обратного вызова открывалась по протоколу <strong>HTTPS</strong>. + Для демонстрации работы авторизации по протоколу <strong>OAuth</strong> используется самоподписанный сертификат. + Браузер вас об этом предупредит. Вы можете проигнорировать это предупреждение, + причин для беспокойства, с учетом изложенного выше, нет. +</p> + + + <h2>Техническая информация</h2> +<p>Последний официальный релиз <strong>Nemiro.OAuth</strong>:</p> +<h3>v{1}</h3> +<p>Версия <strong>Nemiro.OAuth</strong> на этом сервере:</p> +<h3>v{0}</h3> +<p>Номер версии последнего релиза библиотеки <strong>Nemiro.OAuth</strong> может отличаться от номера версии, который размещен на этом сервере. Если номер версии на этом сервере выше, то вероятно в ближайшее время следует ожидать появления новой версии официального релиза.</p> +<ul><li><em>Первое число - основная версия, на данный момент «один». Изменение номера основной версии не гарантирует совместимость с предыдущими номерами основных версий проекта. В ближайшем будущем изменение основной версии не планируется;</em></li> +<li><em>Второе число - младшая версия, меняется при изменении в функционале библиотеки: добавлении новых методов и классов, улучшении старых, удалении не нужных объектов, с сохранением совместимости с предыдущими версиями в рамках основной версии;</em></li> +<li><em>Третье число - содержит информацию о платформе, для которой предназначена сборка. Это целое число, содержащее номер версии <strong>.NET Framework</strong>;</em></li> +<li><em>Четвертое число - номер ревизии в локальной системе контроля версий (номер редакции). Номер может меняться часто и скачками. Этот номер живет своей, отдельной жизнью, не стоит обращать на него особого внимания.</em></li></ul> + + + Демонстрация работы библиотеки Nemiro.OAuth + + + <h2>Полезные ссылки</h2> +<p> + Исходный код:<br /> + <a href="https://github.com/alekseynemiro/nemiro.oauth.dll">https://github.com/alekseynemiro/nemiro.oauth.dll</a> +</p> +<p> + Документация:<br /> + <a href="http://oauth.nemiro.net/">http://oauth.nemiro.net/</a> +</p> +<p> +Готовые формы авторизации для проектов Windows Forms:<br /> +<a href="https://github.com/alekseynemiro/Nemiro.OAuth.LoginForms">https://github.com/alekseynemiro/Nemiro.OAuth.LoginForms</a> +</p> +<p> + Статья: «Авторизация по протоколу OAuth в проектах .NET Framework»:<br /> + <a href="http://kbyte.ru/ru/Programming/Articles.aspx?id=82&mode=art">http://kbyte.ru/ru/Programming/Articles.aspx?id=82&mode=art</a> +</p> +<p> +Видео: «Создание простого менеджера файлов для Dropbox»<br /> +<a href="http://www.youtube.com/watch?v=fcT-Jt8rcdY">http://www.youtube.com/watch?v=fcT-Jt8rcdY</a><br /> +<span style="font-size:11px;">(анг., есть русские субтитры)</span> +</p> +<p> + Другие проекты:<br /> + <a href="http://nemiro.net/">http://nemiro.net/</a> +</p> + + + + Скачать + + + Список друзей + + + Список групп + + + Разрешен<br />протокол<br />HTTP + + + <p>На этой странице выведен список всех зарегистрированных в приложении поставщиков OAuth.</p> +<p>Регистрация поставщиков производится в файле <strong>Global.asax</strong>.</p> +<p>Код перенаправления на авторизацию можно найти в методе <strong>ExternalLogin</strong> контроллера <strong>HomeController</strong>.</p> +<p>Обработка результатов авторизации производится в методе <strong>ExternalLoginResult</strong>.</p> +<p>Попробуйте пройти процедуру авторизации, нажав на любую из кнопок.</p> + + + Установить через <a href="https://www.nuget.org/packages/Nemiro.OAuth/">NuGet</a> + + + Список интересов + + + Внутреннее имя + + + Список лайков + + + Разрешено<br />использовать<br />адреса<br />localhost + + + Разрешено<br />использовать<br />несколько<br />URL + + + <h1 style="color:red;text-align:center;">Этот сайт работает правильно только на домене demo-oauth.nemiro.net!</h1> + <h2 style="color:red;text-align:center;">Используйте другие проекты, для проверки работы с OAuth на локальном сервере.</h2> + + + Примечание + + + Фотоальбомы + + + Все приложения настроены на порт <strong>{0}</strong>.<br />Если у вас используется другой порт, то обработка и вывод результатов авторизации работать не будут.<br />Вы можете явно указать номер порта в вашем веб-приложении (меню: Проект =&gt; Свойства =&gt; вкладка Веб =&gt; Порт), или создать и использовать собственные приложения на сайтах поставщиков (таких как: facebook, twitter, vkontakte и т.п.). + + + Название поставщика + + + Public Key для [{0}] не найден. Пожалуйста, укажите публичный ключ в параметре [oauth:{0}:publicKey], либо удилите клиента [{0}] из параметра [oauth:clients] (файл web.config). + + + Если что-то не работает в <strong>localhost</strong>, вы можете проверить работу библиотеки на сервере <a href="http://demo-oauth.nemiro.net/">http://demo-oauth.nemiro.net/</a>. + + + Срок действия сессии истек. Пожалуйста, пройдите процедуру авторизации повторно, чтобы получить новый маркер доступа для работы с API. + + + Мои твиты + + + Мои преследователи + + + Что нового? + + + Используйте ссылки JavaScript, чтобы исключить их индексацию. Индексация таких ссылок может негативно отразиться на производительности. + + + Информация о пользователе + + + Предупреждение + + + Содержимое Яндекс.Диск + + + Информация о Яндекс.Диск + + + Обновить токен + + + Отозвать токен + + + Показать токен + + + Профиль + + \ No newline at end of file diff --git a/src/Test.OAuthWeb/Views/Home/Index.cshtml b/examples/DemoSite/Views/Home/Index.cshtml similarity index 88% rename from src/Test.OAuthWeb/Views/Home/Index.cshtml rename to examples/DemoSite/Views/Home/Index.cshtml index 475df19..9348524 100644 --- a/src/Test.OAuthWeb/Views/Home/Index.cshtml +++ b/examples/DemoSite/Views/Home/Index.cshtml @@ -1,16 +1,16 @@ @{ - ViewBag.Title = Test.Resources.Strings.DemoTitle; + ViewBag.Title = DemoOAuth.Strings.DemoTitle; Layout = "~/Views/Shared/_Layout.cshtml"; } @if (Request.IsLocal) { - @Html.Raw(Test.Resources.Strings.NoForLocalhost) + @Html.Raw(DemoOAuth.Strings.NoForLocalhost) } -

@Test.Resources.Strings.DemoTitle

+

@DemoOAuth.Strings.DemoTitle

-@Html.Raw(Test.Resources.Strings.DemoIntro) +@Html.Raw(DemoOAuth.Strings.DemoIntro) @* !!!USE JAVASCRIPT LINKS TO PREVENT THEM FROM INDEXING!!! *@