代码之家  ›  专栏  ›  技术社区  ›  Manish Sinha

如何使用C.NET/Mono中的HTTP库来使用请求响应

  •  2
  • Manish Sinha  · 技术社区  · 16 年前

    现在我一直想用 Launchpad's API 用c.net或mono在上面写一个小包装。 按照 OAuth ,我首先需要签署请求,然后 Launchpad has it's own way of doing so .

    我需要做的是创建一个连接到 https://edge.launchpad.net/+request-token 有一些必要的HTTP头,比如 Content-type . 在python中,我有urllib2,但是当我浏览system.net名称空间时,它让我大吃一惊。我不明白该怎么开始。我是否能用这个有很多困惑 WebRequest , HttpWebRequest 或 WebClient . 使用WebClient,我甚至会得到证书错误,因为它们不会作为可信的添加。

    从api文档中,它说需要通过 POST

    • 认证用户密钥:您的用户密钥
    • OAuth_Signature_方法:字符串“纯文本”
    • OAuth_签名:字符串“&”。

    因此,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开发人员不能创建一个我们可以用来读写的类,而不是创建数百个类,并混淆每个新成员。

    1 回复  |  直到 16 年前
        1
  •  3
  •   Cheeso    16 年前

    不,您需要在获取响应流之前关闭请求流。
    像这样:

    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();
                }
            }
        }
    }