如何在C#.NET/Mono中使用HTTP库的请求响应
问题描述:
现在我一直试图使用Launchpad's API
来使用C#.NET或Mono编写一个小封装器。 按照OAuth
,我首先需要得到签署的请求和Launchpad has it's own way of doing so。如何在C#.NET/Mono中使用HTTP库的请求响应
我需要做的是创建一个连接到https://edge.launchpad.net/+request-token与一些必要的HTTP头如Content-type
。在python中我有urllib2,但当我浏览System.Net命名空间时,它吹掉了我的头。我无法理解如何从它开始。我是否可以使用WebRequest
,HttpWebRequest
或WebClient
存在很多混淆。使用WebClient我甚至会得到证书错误,因为它们不是作为可信的添加的。
从API文档,它说,三个按键需要通过POST
- auth_consumer_key来发送:你的消费者的关键
- oauth_signature_method:字符串 “明文字母”
- 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);
我该如何进行furth呃?我应该在clnt
上做一个阅读电话吗?
为什么.NET开发人员不能创建一个我们可以用来读写的类,而不是创建数百个类并混淆每个新手。
答
不,您需要在获取响应流之前关闭请求流。
事情是这样的:
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
{
}
但是,如果你并不需要所有的控制,可以更简单地做一个Web客户端请求。
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();
}
}
}
}
我在此代码http://pastebin.ca/1827416尝试这样做,是得到错误HTTP:// pastebin.ca/1827421 – 2010-03-07 19:11:49
我只是试了完整的代码。我把它贴在上面。这个对我有用。 – Cheeso 2010-03-07 19:36:25
谢谢Cheeso。一旦我回家,我会试试看。 – 2010-03-08 14:05:52