500:尝试从C#控制台调用REST API时出现内部服务器错误

时间:2017-07-19 21:22:05

标签: c# salesforce

我尝试使用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

1 个答案:

答案 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包使用。