我尝试使用oauth从salesforce api生成令牌。我使用此令牌来检索数据,然后对每个对象执行put请求。但是,Web响应显示未处理的异常,表示" 500:内部服务器错误"而我试图生成一个令牌。我需要传递内容类型并接受标题参数和身体中的其他参数。
namespace Test
{
class Program
{
static void Main(string[] args)
{
string response = Post("https://xx-dev.cs15.my.salesforce.com/services/oauth2/token");
dynamic data = JObject.Parse(response);
string accessToken = data.access_token;
}
//POST to generate token.
private static string Post(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.Accept = "application/json";
request.ContentType = "application/x-www-form-urlencoded";
string body = "client_id=43nmbmn43534y98jh_3yQty7vm3CqYMvrSdfdsfFDSGFW7kNYk_bWxmhTaY5KT&client_secret=123456789&grant_type=password&username=user@username.com.test&password=TestPassword";
byte[] byteArray = Encoding.UTF8.GetBytes(body);
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();//**I'm getting the error here**
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();
return responseFromServer;
}
接头: Postman; Application
答案 0 :(得分:-1)
我相信您在正文中传递的内容应该在网址中。 Developer Documentation建议您按照以下方式构建HttpWebRequest
:
string strContent = "grant_type=password" +
"&client_id=" + consumerKey +
"&client_secret=" + consumerSecret +
"&username=" + acctName +
"&password=" + acctPw;
string urlStr = "https://login.salesforce.com/services/oauth2/token?" + strContent;
HttpWebRequest request = WebRequest.Create(urlStr) as HttpWebRequest;
request.Method = "POST";
修改强>
抱歉,我花了很多时间试图让它像你一样使用正文中的内容,但我不断收到“(400)错误请求”作为回复。我不确定你为什么最初得到“500:内部服务器错误”;我使用您使用的完全相同的代码继续收到“(400)错误请求”回复。
开发人员文档中的代码示例对我有用。如果您想尝试,可以使用一些REST包装器;大多数都是NuGet包。见SalesforceSharp。可能值得考虑,因为它可能会减少您必须编写的代码量并减少繁琐。
以下是我从Developer Documentation复制的源代码,如果您想用凭据替换它,看看它是否适合您:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
namespace VerifyRESTTest
{
class Program
{
// Class used for serializing the OAuth JSON response
[DataContract]
public class OAuthUsernamePasswordResponse
{
[DataMember]
public string access_token { get; set; }
[DataMember]
public string id { get; set; }
[DataMember]
public string instance_url { get; set; }
[DataMember]
public string issued_at { get; set; }
[DataMember]
public string signature { get; set; }
}
private static string accessToken = "";
private static string instanceUrl = "";
private static void login()
{
string acctName = "########@gmail.com";
string acctPw = "##############";
string consumerKey = "###############################################";
string consumerSecret = "#################";
// Just for testing the developer environment, we use the simple username-password OAuth flow.
// In production environments, make sure to use a stronger OAuth flow, such as User-Agent
string strContent = "grant_type=password" +
"&client_id=" + consumerKey +
"&client_secret=" + consumerSecret +
"&username=" + acctName +
"&password=" + acctPw;
string urlStr = "https://############-dev-ed.my.salesforce.com/services/oauth2/token?" + strContent;
HttpWebRequest request = WebRequest.Create(urlStr) as HttpWebRequest;
request.Method = "POST";
try
{
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(String.Format(
"Server error (HTTP {0}: {1}).",
response.StatusCode,
response.StatusDescription));
// Parse the JSON response and extract the access token and instance URL
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(OAuthUsernamePasswordResponse));
OAuthUsernamePasswordResponse objResponse = jsonSerializer.ReadObject(response.GetResponseStream()) as OAuthUsernamePasswordResponse;
accessToken = objResponse.access_token;
instanceUrl = objResponse.instance_url;
}
}
catch (Exception e)
{
Console.WriteLine("\nException Caught!");
Console.WriteLine("Message :{0} ", e.Message);
}
}
static void Main(string[] args)
{
login();
if (accessToken != "")
{
// display some current login settings
Console.Write("Instance URL: " + instanceUrl + "\n");
Console.Write("Access Token: " + accessToken + "\n");
Console.Write("Press any key to continue:\n");
Console.ReadKey();
}
}
}
}
需要考虑的一些事项:由于最初尝试示例代码而不是“500:内部服务器错误”时最终收到“(400)错误请求”,因此“HTTP 400”更具体且通常表示语法错误,因此可能值得再次尝试示例方法并确保某些内容未输入错误,并且您的安全令牌,站点密钥,客户端密钥,用户名和密码是正确的,并且您已将安全令牌附加到密码结束。
修改2
了解SalesforceSharp如何在Line 93中使用Salesforce进行身份验证。他们正在使用RestSharp,它可以作为NuGet包使用。