c# desktop app oAuth example

54 posts / 0 new
Last post
David Quail's picture
Joined: 2009-12-01
Dec 17, 2009
c# desktop app oAuth example

Attached is a test app for oauth api n a c# desktop app.  Faith Yasar's c# code was my starting point.  A bit of a refactor of the oAuth librarie to include the oauth_callback parameter was needed, as well as code for displaying the login dialog.The code contained includes a test harness as well as the oauth libraries for oauth login dance and Linkein API requests.  Oauth login is handled with an embedded webBrowser which is shown modally for the user to login.  Upon login completion, dialog will be closed and the token and verifier will be available from the dialogs property.To use the code, simply Add your Linkedin consumer secret and Consumer key to the OauthLinkedIn.cs file: Blogged below with a bit of usage instructions ... but it's pretty easy.http://davidquail.com/2009/12/17/linkedin-oauth-desktop-c-sampleHope that helps some people out.LinkedInOauth.zip

Anonymous (not verified)
Dec 17, 2009

Outstanding, David. Thanks.

Joined: 2010-01-06
Jan 6, 2010

Hi,I have created a desktop application. Got key and secret.When i tried to run the project its stuck after displaying "Recieved Request Token: dajfdfsdflsdaflslflsdfsvsdbvw(not actual token)".Cant do anything. Please tell me what is happening ?Whats is to be given in USER_AGENT ? What is it ?I dont know it but some pages its given "Zend_Http_Client". So i given so.I have changed only three things in your code : values of _consumerKey_consumerSecretUSER_AGENTShould i have to do anything else.Please replyAkeeq

David Quail's picture
Joined: 2009-12-01
Jan 7, 2010

User agent is used as an identifier for your application, ie, for browsers, iphone apps, email applications etc. to identify who they are.  But this value shouldn't matter for the authorize flow.Are you able to step through in code the authorization sequence?  Particularily goNavigateButton_Click event?Is there an exception raised? It sounds like you're getting a request token, but is it not then submitting an authorizeToken request? is _oauth.authorizeToken(); not being hit?

David Quail's picture
Joined: 2009-12-01
Jan 10, 2010

I've updated the code to use a Winform instead of a WPF browser to improve performance.I also discovered that with certain versions of Internet Explorer, the WebBrowser_Navigating or WebBrowser_Navigated events are never sent proper URI event args unless the URI being navigated to is a proper, well formed http, mailto or other special cased uri schemes.  That meant that setting the callback uri to "yourapp://success" breaks on some versions of windows.  I blogged about this here for more details.To work around this, I've changed the sample to redirect to our domain.  If you've got a domain you control, I'd suggest using this updated code and setting the callback to your domain.  If you don't have a domain, you can always set it to something known like "http://www.linkedin.com"  Either situation isn't ideal because your code is dependent on a server, but it's better than breaking on certain versions of windows.

David Quail's picture
Joined: 2009-12-01
Jan 29, 2010

Code available on github.  Hope that makes it easier for people.http://github.com/dquail/LinkedinOauth

Muhammad Adil's picture
Joined: 2010-02-22
Feb 22, 2010

David, Can you please provide me the example of C# Desktop Application (Not xaml) To Get contacts (connections List) name and Email Address RegardAdil

Justin Barnes's picture
Joined: 2010-01-29
Jan 29, 2010

Fantastic software it's been a real help to me, many thanks, your a great guy for posting it.However, I have a question, is it possible to automate the authentication against LinkedIn?You would of course have to include your user name and password somewhere within the software and post it accordingly....

Anonymous (not verified)
Feb 1, 2010

Hi Justin,Just a reminder that while we encourage inventive integrations of almost any kind, automating the login process (even with your own login credentials) is strictly forbidden. Thanks!Taylor

Justin Barnes's picture
Joined: 2010-01-29
Feb 1, 2010

I quite understand, no problem.The user needs to authenticate but I just want to avoid doing it every time, from what I understand the authentication only happens once.

Justin Barnes's picture
Joined: 2010-01-29
Feb 1, 2010

For desktop apps or mobile apps I need to authenticate through internet explorer?  is this correct, I know I can authorize the token for say...30 days.Is there another way to authenticate other than a browser?

Anonymous (not verified)
Feb 1, 2010

Hi Justin,Authenticating via a web browser, whether Internet Explorer or otherwise, is required, yes. It's up to the user to authorize how long the auth token will be valid for, and the user can sever that authority at any time. When an access token is invalid, you'll get a 401 Unauthorized HTTP response code along with an XML document in the body of the response describing that the access token is invalid.Thanks,Taylor

Justin Barnes's picture
Joined: 2010-01-29
Feb 2, 2010

Thank you, therefore I just need to keep a copy of the token and when it expires ask the user to authenticate again, got it.  Thanks for your help.

David Quail's picture
Joined: 2009-12-01
Feb 1, 2010

Hello Justin,Once a user has authenticated you'll have access to the token secret, verifier and token.  Given these credentials, your software can access the api without future authentication calls.Does that answer what you're asking about?

Joined: 2010-02-21
Feb 21, 2010

Hey David,First of all I want to thank you for sharing this nice oAuth application.Just wanted to know, how did you set call back url to "liconnect://success" ?How is it working for this value?Thanks a lot in advance!!- Abhishek

David Quail's picture
Joined: 2009-12-01
Feb 22, 2010

Hello Abhishek,You set the callback to liconnect:// url in the call to get the Request token.However, for reasons I explain in this blog posting, I no longer am setting the url to this callback.  Essentially older versions of internet explorer are swallowing the redirect url to that address.  I've uploaded the sample code to github: http://github.com/dquail/LinkedinOauthHope that helps.

- -
Joined: 2009-11-25
Feb 24, 2010

Hi David,Thanks for the application in WPF. I have already developed application in asp.net.Thanks,Ibrahim

Joined: 2010-11-01
Nov 23, 2010

Hi David, Me againSeems you know alot about this.My problem is the following:I have used your Desktop App as a base for my webservice ( see attached  PNG).As you can see, i have gotten alomost everything to work 100%, except for 2 very important features.Sending messages between Connections, and sending Invites. I have googled and searched and tried, but I keep on getting 401 Unauthorized on the 2 calls....It can't be the auth, as it is working for all the others, even the Update Status - The only difference between all my calls and these 2, are the fact that they 'POST' the data (Update status uses 'PUT', and it works fine)I have posted multiple places, with Base strings and Signatures and headers, but no one really seems to know how to assist me.I can probbly use a 3rd party dll, like codeplex, but I would prefer to get this working on my own, so that i understand better what I am doing, as my Linkedin Integration will be the first of many other oAuth implementations.Hope you can give me more insight into how to build and send the messages/invites using C#.ThanxM

Joined: 2010-11-01
Nov 23, 2010

I just picked up something interresting, which might help you all to help me  !Twitter API also uses OAuth, so I figured lets quickly test there, and here is what i have established:Any Call that Uses the 'GET' Method, works 100%Where Specified that 'PUT' will work, it does (Linkedin Status Updates)On ANY calls made, using 'POST' as the method, I get a 401 Unauthorized - On both Linkedin and Twitter.I have checked, and rechecked the basestring, signiture and headers, and all looks fine.I have tried multiple different methods to actually write the data that gets posted, but still to no avail.Hopefully this can give an indication as to where i am going wrong, as it narrows it down to 'POST' methods..Thanx in AdvanceM

Joined: 2010-06-28
Dec 27, 2010

Hi guys,Here you find a simplified code from the existing code.What you have to do is, first get you api and secret keys from your developer account. Set them in appSettings.config file. After then set call back url at "OAuth Redirect URL" field at your Linkedin developer's account (see attachment bellow) where you found your API and secret key. This call back url will be same as the localhost you created. suppose http://localhost/linkedinoauth/default.aspx is your localhost url, then the same will be your call back url on your application's API account on developer.linkedin.com.this code contains Set Status, Invitation and Show Profile methods. In the same way you can made for other features also.Cheers...

Nilesh Gokhale's picture
Joined: 2010-04-05
Apr 5, 2010

This was an awesome example... I am trying to use this as a baseline and putting it to work through my Web Application. Would this code work?When I try to run this, through web app it always throws an errorThe remote server returned an error: (401) Unauthorized.When I debugged both applications I found out that the postdata is different in both apps.Am I doing something wrong...Really need help in this..Thanks,Nilesh

Joined: 2010-04-08
Apr 8, 2010

Hi David,Thank you very much for uploading your example code, it was incredibly helpful seeing an out of band oauth implementation.I have a question about a scenario your test harness doesn't cover. If you've previously prompted the user to input their Linked-In credentials and persisted the authorization token/verifier returned from that initial authorization, how do you go about accessing the API without prompting them again provided the token hasn't yet expired? In this scenario, your winforms application would have been shut down between the initial authorization and subsequent API request.Thanks in advance.

Joined: 2010-04-08
Apr 8, 2010

After much trial and error, I was able to successfully call the OAuthLinkedIn.APIWebRequest method without re-prompting the user for authentication. I am not certain this is 100% correct given most posts and documentation I've read about OAuth state that you only need the Access Token for subsequent calls. However, I consistently got "401 unauthorized" responses until I did the following:

  1. After prompting the user for initial authentication and obtaining an Access token, persist the access token (e.g.OAuthLinkedIn.Token), the token secret (e.g.OAuthLinkedIn.TokenSecret), and verifier (e.g.OAuthLinkedIn.Verifier).
  2. Retrieve the values from wherever they were persisted (if between application sessions) and set all 3 properties on your OAuthLinkedIn instance prior to calling the APIWebRequest method.
Dheeraj Kumar's picture
Joined: 2010-05-18
May 18, 2010

HI , i am developing an window application , i am able to get verifier and request code but when i try to get accessToken i get error "The remote server returned an error: (401) Unauthorized."Please guid me where i am wrong .I have attached my Oauth , that i using to send request .Please help meThank you

Dheeraj Kumar's picture
Joined: 2010-05-18
May 18, 2010

hi David Quail , i downloaded your sample application (Winform one) , but its not getting verifier from URl and giving Exception ,please let me know how can i make this run properlyThank youDheeraj Kumar

Nishant Kumar's picture
Joined: 2010-05-29
May 29, 2010

Hi,     I am new to Linkedin API. I am developing a desktop application that extracts information from linkedin profile.    I want to automate the procedure of granting access by the user. I mean that when I execute the application by giving the public profile url in input, the information from the profile is displayed as output.    Please let me know if it is possible ?

Joined: 2010-04-08
May 31, 2010

Hi Nishant,Yes, it is possible to integrate Linked-In data with your desktop application. However, you can't do this in a completely automated fashion. Each user of your application must explicitly grant you access to their account. The Linked-In terms and conditions don't allow you to automate the oauth process (i.e. auto-filling user credentials, etc) in any manner.Hope this answers your question.BW

Nishant Kumar's picture
Joined: 2010-05-29
Jun 1, 2010

Thanks Brian for the information. I got the answer of my question.

Kalyan Krishna's picture
Joined: 2010-06-10
Jun 10, 2010

Thanks a lot David.amazing peice of work and a great help

- -
Joined: 2010-05-18
Jun 23, 2010

Hi David,Thank you again for your great sample code. It has been very helpful.Can you help me understand what I might be doing wrong with the following test cases? It should be working but maybe the URL=... is getting URLencoded?https://api.linkedin.com/v1/people/~:(id,first-name,last-name,industry,) - workshttps://api.linkedin.com/v1/people/id=XXX:(id,first-name,last-name,industry) - works where XXX is an ID (for example, sFkNlelTXX) -- XX is something else ==but I get the following resultThe remote server returned an error: (400) Bad Request.for each of the following test cases https://api.linkedin.com/v1/people/url=http%3A%2F%2Fwww.linkedin.com%2Fin%2Ftaylorsingletary http://api.linkedin.com/v1/people/url=http%3A%2F%2Fwww.linkedin.com%2Fin%2Ftaylorsingletary https://api.linkedin.com/v1/people/url=http%3A%2F%2Fwww.linkedin.com%2Fin%2Ftaylorsingletary:public https://api.linkedin.com/v1/people/url=http%3A%2F%2Fwww.linkedin.com%2Fin%2Ftaylorsingletary:(id,first-name) tried the following (but got bad request) In case libary is escaping some of the characters again:https://api.linkedin.com/v1/people/url=http://www.linkedin.com/in/taylorsingletary:(id,first-name)andhttp://api.linkedin.com/v1/people/url=http://www.linkedin.com/in/taylorsingletary I noticed that oAuthBase reserved chars include "-_.~" so I am wondering if oAuthBase may already be encoding them in it's URLencode -- so it the "." in www.linkedin.com getting encoded or something??? Is it possible that the followng "APIWebRequest" line encodes the URL: parameter already at the linebyte[] fileToSend = Encoding.UTF8.GetBytes(postData);? Also, can you confirm that this line in WebRequest is always correctwebRequest.ContentType = "application/x-www-form-urlencoded"; ? I am still learning CSharp so apologize if this is a dumb question... Is there a way to see what is actually being sent (e.g., print fileToSend?) Also, would it be useful to add some of my working code to the sample? Thanks again! Regards,-Andrew Here is what I previously asked on the forum where Adam Trachtenberg says "This should work. Verify that this is the actual URL you're sending. Maybe your library is escaping some of the characters again?" Any suggestions? Andrew Duquet4 posts since May 18, 201010. Jun 23, 2010 10:12 AM in response to: Jack VliegendhartRe: Problems with standard and public profile urlsHi Jack,Is this still working for you? I am able to get the following line to work per the C# example coderesponse = "\n" + _oauth.APIWebRequest("GET", "https://api.linkedin.com/v1/people/~:(id,first-name,last-name,industry,)", null); //was null but I want the full profile and DOC-1002 says add more //WORKS! Yeah!and the following worksresponse = "\n" + _oauth.APIWebRequest("GET", "https://api.linkedin.com/v1/people/id=XXXXXXXXXX:(id,first-name,last-name,industry)", null); //works when I replace XXXXXXXXXX with an IDbut the following 3 attempts at using the Public-URL results in "The remote server returned an error: (400) Bad Request."response = "\n" + _oauth.APIWebRequest("GET", "http://api.linkedin.com/v1/people/url=http%3A%2F%2Fwww.linkedin.com%2Fin%2Ftaylorsingletary:id, first-name", null);andresponse = "\n" + _oauth.APIWebRequest("GET", "http://api.linkedin.com/v1/people/url=http%3A%2F%2Fwww.linkedin.com%2Fin%2Ftaylorsingletary:(id,first-name)", null);andresponse = "\n" + _oauth.APIWebRequest("GET", "http://api.linkedin.com/v1/people/url=http%3A%2F%2Fwww.linkedin.com%2Fin%2Ftaylorsingletary:public", null);I would think this would work per the 8th. reply (Dec 28, 2009 8:25 AM) on http://developer.linkedin.com/thread/1378  (copied below)8. Dec 28, 2009 8:25 AM in response to: Ibrahim KhanRe: Problems with standard and public profile urlsThe URLs will need to be URL-escaped so they aren't misinterpreted.For example:

http://www.linkedin.com/in/taylorsingletary

should be encoded as

http%3A%2F%2Fwww.linkedin.com%2Fin%2Ftaylorsingletary

So that your Request URI would be something like:

http://api.linkedin.com/v1/people/url=http%3A%2F%2Fwww.linkedin.com%2Fin%2Ftaylorsingletary:public

Apparently this works on some java samples so I must be doing something wrong. any suggestions would be greatly appreciated!Regards,-AndrewIf you would like to reply, please log in with your LinkedIn account credentials.Adam Trachtenberg48 posts since Apr 8, 201011. Jun 23, 2010 11:46 AM in response to: Andrew DuquetRe: Problems with standard and public profile urls

http://api.linkedin.com/v1/people/url=http%3A%2F%2Fwww.linkedin.com%2Fin%2Ftaylorsingletary:public

This should work. Verify that this is the actual URL you're sending. Maybe your library is escaping some of the characters again?

- -
Joined: 2010-05-18
Jun 25, 2010

Hi David/All,I think Adam's right. When I send a request for " https://api.linkedin.com/v1/people/url=http%3A%2F%2Fwww.linkedin.com%2Fin%2Ftaylorsingletary:(id,first-name)" I sniff back ""https://api.linkedin.com/v1/people/url=http%3A//www.linkedin.com/in/taylorsingletary:(id,first-name)" which makes it appear to me that the "/" is being converted back from %2F .https://api.linkedin.com/v1/people/url=http%3A//www.linkedin.com/in/taylorsingletary:(id,first-name)api.linkedin.comGETtext/xml;charset=utf-8400 Bad Request49000.1660156250.344726563Any suggestions?I am a C# newbie. Can anyone else using this C# desktop app get this work? Specifically, any suggestions on perhaps modifying the routine APIWebRequest linebyte[] fileToSend = Encoding.UTF8.GetBytes(postData); or something like that?Regards,-Andrew

Arian Geertsema's picture
Joined: 2009-11-27
Aug 10, 2010

I know it's quite a while since the last post, but there's a desktop sample available in the latest code drop of the LinkedIn Developer Toolkit.Hope this helps.

Muhammad Saeed Anwar's picture
Joined: 2011-07-17
Jul 17, 2011

Dear David, really good source you have provided. we are doing a project using your source. can i contact further regarding this. can you provide your contacts.

Ross Kelly's picture
Joined: 2011-07-25
Jul 26, 2011

Hi David. Thanks. I managed to get your code working and can connect to LinkedIn and manage to retrieve my profile.
I have a problem when I try to get a public profile. It seems there is some issue with encoding but I can't get it to work.

Neither of these strings work (C#):

string url1 = "http://au.linkedin.com/pub/jinsiu-du/6/75/683";
string url2 = "http" + "%3A%2F%2Fau.linkedin.com%2Fpub%2Fjinsiu-du%2F6%2F75%2F683";
txtOutput.Text += "\n" + _oauth.APIWebRequest("GET", "https://api.linkedin.com/v1/people/url=" + url1, null);

Greensboro NC's picture
Joined: 2011-06-09
Jul 26, 2011

Got it working now.
Thank you

Mohammad Salmaan's picture
Joined: 2011-03-28
Nov 4, 2011

thanks David for sharing great application

as i have downloaded desktop app and run that giving perfect result by your app we can get our profile information as i need to crawl the information of other one also which are not in my linkedIn connectivity , how can i crawl the information any help or any example , waiting for the reply.

Kirsten Hunter's picture
Joined: 2011-06-30
Nov 4, 2011

What is your use case here? Storing information from LinkedIn is forbidden by our terms of use, and the API is designed to allow you to create an alternative experience for a member with the information they can view, not copy our database into your application.

Mohammad Salmaan's picture
Joined: 2011-03-28
Nov 8, 2011

Is there any way to find total how many person are using linkedin ..or where can i get the information of linkedIn users

- -
Joined: 2011-08-23
Nov 22, 2011

Anyone get this working for a winforms desktop application as well? When created the Navigating Event, the WebBrowser tool uses WebBrowserNavigatingEventArgs instead of NavigatingCancelEventArgs (used in the above WPF example). This returns a Url and not a Uri and the query string does not contain the verifier in the query string from linkedin. Any help is appreciated. Thanks!

- -
Joined: 2011-08-23
Nov 22, 2011

nm i got it. its in the newer example he provided.

Josie Musto's picture
Joined: 2011-11-25
Nov 26, 2011

Seems like LinkedIn has made it really difficult, if not impossible, and illegal, for WinForms .Net developers to search their content.

Joined: 2011-12-20
Dec 22, 2011

Want to add >> make sure that the clock on your computer is correct spent two days debugging when half the time it was working as it took me that long to step though the code simply because my clock was 5 mins fast.

Joined: 2011-12-13
Jan 4, 2012

David - thank you sir! Worked first try - now I understand what Faith Yasar was trying to do. I am making a console application that will be sending out a new quote each day.

Abhishek Singh's picture
Joined: 2012-01-17
Jan 18, 2012

Great work David.Like the concept of callback url.But how to find the user's connections or contacts.

Thanks,
Abhishek

Venkat Krishna's picture
Joined: 2012-04-27
May 1, 2012

hi david its working thank you but i want in asp.net not for on wpf if you possible do that send to me that example please yaar my email id venkat.mca35@gmail.com

Sumit Thapar's picture
Joined: 2012-05-06
May 8, 2012

I dont know how to thank you David..Hats off to you...

Neil Varnas's picture
Joined: 2012-06-13
Jun 27, 2012

Guys, could anyone help pelase, Especially David Since You`ve odnr this. My problem is that i cant submit the retreved values to my server. This is what Ive got :
cript type="text/javascript" src="http://platform.linkedin.com/in.js">
api_key: kpgzzirra6gk
onLoad: onLinkedInLoad
authorize: true
</script>

<script type="text/javascript">

function onLinkedInLoad()
{
IN.Event.on(IN, "auth", onLinkedInAuth);
}

function onLinkedInAuth()
{
IN.API.Profile("me").result(displayProfiles)
.fields("firstName", "lastName", "id")
.result(displayProfiles)
.error(displayProfilesErrors);
}

function displayProfiles(profiles)
{
var profilesDiv = document.getElementById("profiles");
var members = profiles.values;
$('#firstName').val(profiles.values[0].firstName);
$('#secondName').val(profiles.values[0].lastName);
$('#id').val(profiles.values[0].id);
if (IN.User.isAuthorized()) { $('form').submit(); }
for (var member in members)
{
profilesDiv.innerHTML += "<p>" + members[member].firstName + " " + members[member].lastName
+ " works in the " + members[member].id + " id.";
}
}
function displayProfilesErrors(error)
{
profilesDiv = document.getElementById("profiles");
profilesDiv.innerHTML = "<p>Oops!</p>";
console.log(error);
}
</script>

and ive got my 3 empty fields in the body where im trying t save those 3 values:
<form id="form1" runat="server">
<input id="firstName" type="hidden" name="firstName" value="" />
<input id="secondName" type="hidden" name="lastName" value="" />
<input id="id" type="hidden" name="id" value="" />
<div id="profiles"></div>

and in code behind im creating a db where iw ant to get the values from those hidden fields:

if (Request["firstName"] != string.Empty && Page.IsPostBack)
{

Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyDbContext>());
var person = new Person
{
FirstName = Request["firstName"],
LastName = Request["lastName"],
Industry = Request["id"]
};

using (var context = new MyDbContext())
{
context.Persons.Add(person);
context.SaveChanges();
}
}
}

Please some1 help me ;/. BTW I do get the values but that line if (IN.User.isAuthorized()) { $('form').submit(); } keeps on submitting my form on and on , because its in the loop. How to get that JS code right?

Joined: 2012-07-05
Jul 6, 2012

Thank You very much...David Quail....it really hepls me a lot....prakash chasiya

Ankit Choure's picture
Joined: 2012-07-13
Sep 7, 2012

Hi, Please share solution
i am getting same error

Joined: 2012-09-03
Oct 2, 2012

Hi all,

I need help. I'm using David's example. I'm able to authorize and get the profile of the user. The issue is that I need to retrieve other things too. I need to retrieve the connections of the user and the messages sent/received by the user. Is it possible? If so, where are the changes that I need to make in the codes done by David.

Regards,
Hazim

Kamyar Mohager's picture
LinkedIn Employee
Joined: 2012-04-04
Oct 3, 2012

Hi Hazim, in an earlier thread you mentioned you were able to set your scope parameters for member permissions. If that's the case, feel free to share with the rest of the community :)

Thanks!
Kamyar

Pages