2010-03-07 4 views
2

Прямо сейчас я пытаюсь использовать Launchpad's API, чтобы написать небольшую оболочку поверх него с помощью C# .NET или Mono. В соответствии с OAuth, мне сначала нужно получить подписанные запросы и Launchpad has it's own way of doing so.Как использовать запрос-запрос с использованием HTTP-библиотек в C# .NET/Mono

Что мне нужно сделать, так это создать соединение с https://edge.launchpad.net/+request-token с некоторыми необходимыми HTTP-заголовками, такими как Content-type. В python у меня есть urllib2, но когда я заглянул в пространство имен System.Net, он сдул мне голову. Я не мог понять, как начать с него. Есть много путаницы, могу ли я использовать WebRequest, HttpWebRequest или WebClient. С WebClient я даже получаю ошибки сертификата, поскольку они не добавляются как надежные.

От Docs API, он говорит, что три ключа нужно отправить через POST

  • auth_consumer_key: Ваш потребитель ключ
  • oauth_signature_method: Строка "PLAINTEXT"
  • oauth_signature: Строка "&" ,

Так запрос HTTP может выглядеть следующим образом:

POST /+request-token HTTP/1.1 
Host: edge.launchpad.net 
Content-type: application/x-www-form-urlencoded 

oauth_consumer_key=just+testing&oauth_signature_method=PLAINTEXT&oauth_signature=%26 

ответные действия должны выглядеть следующим образом:

200 OK 

oauth_token=9kDgVhXlcVn52HGgCWxq&oauth_token_secret=jMth55Zn3pbkPGNht450XHNcHVGTJm9Cqf5ww5HlfxfhEEPKFflMqCXHNVWnj2sWgdPjqDJNRDFlt92f 

Я изменил код много раз, и, наконец, все, что я могу получить его что-то вроде

HttpWebRequest clnt = HttpWebRequest.Create(baseAddress) as HttpWebRequest; 
// Set the content type 
clnt.ContentType = "application/x-www-form-urlencoded"; 
clnt.Method = "POST"; 

string[] listOfData ={ 
    "oauth_consumer_key="+oauth_consumer_key, 
    "oauth_signature="+oauth_signature, 
    "oauth_signature_method"+oauth_signature_method 
}; 

string postData = string.Join("&",listOfData); 
byte[] dataBytes= Encoding.ASCII.GetBytes(postData); 

Stream newStream = clnt.GetRequestStream(); 
newStream.Write(dataBytes,0,dataBytes.Length); 

Как исправить э? Должен ли я читать запрос на clnt?

Почему разработчики .NET не могут создать один класс, который мы можем использовать для чтения и записи вместо создания сотен классов и смущения каждого новичка.

ответ

3

Нет, вам нужно закрыть поток запросов, прежде чем получать поток ответов.
Что-то вроде этого:

Stream s= null; 
try 
{ 
    s = clnt.GetRequestStream(); 
    s.Write(dataBytes, 0, dataBytes.Length); 
    s.Close(); 

    // get the response 
    try 
    { 
     HttpWebResponse resp = (HttpWebResponse) req.GetResponse(); 
     if (resp == null) return null; 

     // expected response is a 200 
     if ((int)(resp.StatusCode) != 200) 
      throw new Exception(String.Format("unexpected status code ({0})", resp.StatusCode)); 
     for(int i=0; i < resp.Headers.Count; ++i) 
       ; //whatever 

     var MyStreamReader = new System.IO.StreamReader(resp.GetResponseStream()); 
     string fullResponse = MyStreamReader.ReadToEnd().Trim(); 
    } 
    catch (Exception ex1) 
    { 
     // handle 404, 503, etc...here 
    } 
}  
catch 
{ 
} 

Но если вам не нужно все контролировать, вы можете сделать запрос WebClient более просто.

string address = "https://edge.launchpad.net/+request-token"; 
string data = "oauth_consumer_key=just+testing&oauth_signature_method=...."; 
string reply = null; 
using (WebClient client = new WebClient()) 
{ 
    client.Headers.Add("Content-Type","application/x-www-form-urlencoded"); 
    reply = client.UploadString (address, data); 
} 

Полный рабочий код (компиляции в .NET v3.5):

using System; 
using System.Net; 
using System.Collections.Generic; 
using System.Reflection; 

// to allow fast ngen 
[assembly: AssemblyTitle("launchpad.cs")] 
[assembly: AssemblyDescription("insert purpose here")] 
[assembly: AssemblyConfiguration("")] 
[assembly: AssemblyCompany("Dino Chiesa")] 
[assembly: AssemblyProduct("Tools")] 
[assembly: AssemblyCopyright("Copyright © Dino Chiesa 2010")] 
[assembly: AssemblyTrademark("")] 
[assembly: AssemblyCulture("")] 
[assembly: AssemblyVersion("1.1.1.1")] 

namespace Cheeso.ToolsAndTests 
{ 
    public class launchpad 
    { 
     public void Run() 
     { 
      // see http://tinyurl.com/yfkhwkq 
      string address = "https://edge.launchpad.net/+request-token"; 

      string oauth_consumer_key = "stackoverflow1"; 
      string oauth_signature_method = "PLAINTEXT"; 
      string oauth_signature = "%26"; 

      string[] listOfData ={ 
       "oauth_consumer_key="+oauth_consumer_key, 
       "oauth_signature_method="+oauth_signature_method, 
       "oauth_signature="+oauth_signature 
      }; 

      string data = String.Join("&",listOfData); 

      string reply = null; 
      using (WebClient client = new WebClient()) 
      { 
       client.Headers.Add("Content-Type","application/x-www-form-urlencoded"); 
       reply = client.UploadString (address, data); 
      } 

      System.Console.WriteLine("response: {0}", reply); 
     } 

     public static void Usage() 
     { 
      Console.WriteLine("\nlaunchpad: request token from launchpad.net\n"); 
      Console.WriteLine("Usage:\n launchpad"); 
     } 


     public static void Main(string[] args) 
     { 
      try 
      { 
       new launchpad() 
        .Run(); 
      } 
      catch (System.Exception exc1) 
      { 
       Console.WriteLine("Exception: {0}", exc1.ToString()); 
       Usage(); 
      } 
     } 
    } 
} 
+0

Я попробовал это в этом коде http://pastebin.ca/1827416 и получал ошибку HTTP: // pastebin.ca/1827421 –

+0

Я просто попробовал полный код. Я разместил его выше. Меня устраивает. – Cheeso

+0

Спасибо Cheeso. Попробуй, как только я вернусь домой. –