简体   繁体   中英

Error 400: Bad Request while posting through LinkedIn Share API

I have checked a bunch of questions on StackOverflow which may be termed as related but most of them are either too old or too specific, and doesn't help me much.

While working on an application that helps schedule posts on LinkedIn, I follow below process:

  1. Allow user to Sign-up using their LinkedIn account.
  2. After they submit for Sign-up, I store Access Token , Refresh Token and relevant TTL along with the user details.
  3. When they schedule a post at a specific time, I have an Azure function (serverless) that checks for any post to submit every minute, and supposed to post on user's behalf.
  4. Using the Access Token that I saved earlier, I hit https://api.linkedin.com/v2/me to get the person:id of the user. Everything works as expected until here and gets the person:id using GetPersonID()

See my code below for posting using API:

      string pid = GetPersonID();
      sstring PostCode = @"{""content"":{""contentEntities"":[{""entityLocation"":""" + URL + @""",""thumbnails"":[{""imageSpecificContent"":{},""resolvedUrl"":""" + OriginalURL + @"""}]}],""description"":"" + URL + "",""title"":""" + Title + @"""},""distribution"":{""linkedInDistributionTarget"":{}},""owner"":""urn:li:person:" + pid + @""",""subject"":""" + Title + @""",""text"":{""text"":""" + Description + @"""}}";
      string outJ = JsonConvert.SerializeObject(PostCode);
      WebClient clientx = new WebClient();
      clientx.Headers.Add("Authorization", "Bearer " + access_token);
      clientx.Headers.Add("X-Restli-Protocol-Version", "2.0.0");
      clientx.Headers.Add("x-li-format", "json");
      clientx.Headers["Content-Type"] = "application/json";
      System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
      string LinkedInAccessTokenURL = "https://api.linkedin.com/v2/shares";
      string result = clientx.UploadString(LinkedInAccessTokenURL, "POST", data: outJ);

A Sample Json Post

    {"content":{"contentEntities":[{"entityLocation":"http://www.test.com","thumbnails":[{"imageSpecificContent":{},"resolvedUrl":"https://picsum.photos/200/300"}]}],"description":" + URL + ","title":"This is a test post"},"distribution":{"linkedInDistributionTarget":{}},"owner":"urn:li:person:<person:id>","subject":"This is a test post for LinkedIn API","text":{"text":"ashdjahs dadjh asdjahs da\nahs djashdjkashdas\nahsd jasdhkjasdh "}}

Everything works until the last line of the above code. Upon POST the LinkedIn API throws an error System.Net.WebException: 'The remote server returned an error: (400) Bad Request.' ( LinkedIn documentation reference ). I've even tried posting the value in PostCode using Postman and it works perfectly fine, which tells me that the JSON generated it correct.

But despite multiple tries and fixes, nothing seems to work for actual Post .

Exception thrown:

Data: {System.Collections.ListDictionaryInternal}
HResult: -2146233079
HelpLink: null
InnerException: null
Message: "The remote server returned an error: (400) Bad Request."
Response: {System.Net.HttpWebResponse}
Source: "System.Net.Requests"
StackTrace: "   at System.Net.HttpWebRequest.GetResponse()\r\n   at System.Net.WebClient.GetWebResponse(WebRequest request)\r\n   at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream)\r\n   at System.Net.WebClient.UploadBits(WebRequest request, Stream readStream, Byte[] buffer, Int32 chunkSize, Byte[] header, Byte[] footer)\r\n   at System.Net.WebClient.UploadDataInternal(Uri address, String method, Byte[] data, WebRequest& request)\r\n   at System.Net.WebClient.UploadString(Uri address, String method, String data)\r\n   at System.Net.WebClient.UploadString(String address, String method, String data)"
Status: ProtocolError
TargetSite: {System.Net.WebResponse GetResponse()}

Marking as resolved.

The issue was apparently with the Json being generated. Probably it was encoding, but I'm still confused on how Postman was able to post it without any issues.

I created relevant class, and then using its object, I serialized it into Json using Newtonsoft . Which after passing to the WebClient object rendered the correct results.

Lessons learnt!

I know manually creating a JSON is never a good idea (what I actually did earlier, to save time), but at times being lazy can make you work harder than you would have in the first place. So if we're planning to do an API call with JSON as payload, its never a waste of time to create a relevant class and then serialize to Json.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM