我用c#使用google的picasa接口,尝试写了一个上传文件的试验程序.下面说说自己的感想
在http请求时如果要附带上附件,不可避免的需要用到multipart的content-type。具体使用是在http中把content-type改成相应的multipart类型,并且加上boundry标记作为分隔符。
需要注意两点(搞了我好久)..
如果
ContentType = "multipart/related; boundary= BOUNDARY";
除了最后一个boudry,其他的boundry格式如下
--BOUNDARY/r/n //注意前面的"--"还有/r/n
最后一个分隔符如下
--BOUNDARY--/r/n //注意前后“--”还有/r/n
再写每一段的Content-Type等信息的时候,需要注意用逗号隔开,并且最后要空两行
如
streamWriter.Write("Content-Type: application/atom+xml/r/n/r/n"); //注意空了两行。
举个c#写的用来上传google picsaca的例子
具体reference是
http://code.google.com/apis/picasaweb/gdata.html
谈谈那我参考的一些文档:
Writing C# code for a multipart file upload to a Java servlet : http://blog.mindbridge.com/?p=59
在http请求时如果要附带上附件,不可避免的需要用到multipart的content-type。具体使用是在http中把content-type改成相应的multipart类型,并且加上boundry标记作为分隔符。
需要注意两点(搞了我好久)..
如果
ContentType = "multipart/related; boundary= BOUNDARY";
除了最后一个boudry,其他的boundry格式如下
--BOUNDARY/r/n //注意前面的"--"还有/r/n
最后一个分隔符如下
--BOUNDARY--/r/n //注意前后“--”还有/r/n
再写每一段的Content-Type等信息的时候,需要注意用逗号隔开,并且最后要空两行
如
streamWriter.Write("Content-Type: application/atom+xml/r/n/r/n"); //注意空了两行。
举个c#写的用来上传google picsaca的例子
具体reference是
http://code.google.com/apis/picasaweb/gdata.html
using
System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
namespace WindowsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
WebRequest req = WebRequest.Create("https://www.google.com/accounts/ClientLogin");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
Stream stream = req.GetRequestStream();
StreamWriter streamWriter = new StreamWriter(stream, Encoding.ASCII);
streamWriter.Write("accountType=HOSTED_OR_GOOGLE");
streamWriter.Write("&Email=binwind1984@gmail.com");//帐号换成你自己的
streamWriter.Write("&Passwd=XXX");//密码换成你自己的
streamWriter.Write("&service=lh2");
streamWriter.Write("&source=bin-test-1.0");
streamWriter.Close();
stream.Close();
WebResponse rep = req.GetResponse();
Stream responseStream = rep.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream, Encoding.ASCII);
string a = responseReader.ReadToEnd();
TokenCollection tokens = new TokenCollection(a, '=', true, 2);
string token = TokenCollection.FindToken(tokens, "Auth");
responseReader.Close();
responseStream.Close();
req = WebRequest.Create("http://picasaweb.google.com/data/feed/api/user/binwind1984/album/UntitledAlbum");
//binwind1984替换为相应的帐号,UntitledAlbum替换为相应的相册名字
string boundry = "-----xxxxxxxBOUNDERxxxxdxx";
req.ContentType = "multipart/related; boundary="" + boundry + """;
//req.ContentType = "image/jpeg";
HttpWebRequest httpReq = req as HttpWebRequest;
httpReq.AllowAutoRedirect = false;
req.Method = "POST";
req.Headers.Add("Authorization: GoogleLogin auth=" + token);
req.Headers.Add("MIME-version: 1.0");
stream = req.GetRequestStream();
streamWriter = new StreamWriter(stream, Encoding.ASCII);
streamWriter.WriteLine("Media multipart posting");
streamWriter.Write("--" + boundry + " ");
streamWriter.Write("Content-Type: application/atom+xml ");
//streamWriter.WriteLine("<?xml version='1.0' encoding='UTF-8'?>");
streamWriter.WriteLine("<entry xmlns="http://www.w3.org/2005/Atom">");
streamWriter.WriteLine("<title>test document</title>");
streamWriter.WriteLine("<summary>Darcy on the beach</summary>");
streamWriter.WriteLine("<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/photos/2007#photo"/>");
streamWriter.WriteLine("</entry>");
streamWriter.Write("--" + boundry + " ");
streamWriter.Write("Content-Type: image/jpeg ");
streamWriter.Flush();
FileStream fs = new FileStream("C:/s.jpg", FileMode.Open);//这里假设上传c:s.jpg文件.
byte[] bytes = new byte[1024];
while (fs.CanRead)
{
int read = fs.Read(bytes, 0, 1024);
stream.Write(bytes, 0, read);
if (read == 0)
{
break;
}
}
fs.Close();
stream.Flush();
streamWriter.Write("--" + boundry + "--" + " ");
streamWriter.Close();
stream.Close();
try
{
rep = req.GetResponse();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
public class TokenCollection : IEnumerable
{
private string[] elements;
/// <summary>Constructor, takes a string and a delimiter set</summary>
public TokenCollection(string source, char[] delimiters)
{
if (source != null)
{
this.elements = source.Split(delimiters);
}
}
/// <summary>Constructor, takes a string and a delimiter set</summary>
public TokenCollection(string source, char delimiter,
bool seperateLines, int resultsPerLine)
{
if (source != null)
{
if (seperateLines == true)
{
// first split the source into a line array
string[] lines = source.Split(new char[] { ' ' });
int size = lines.Length * resultsPerLine;
this.elements = new string[size];
size = 0;
foreach (String s in lines)
{
// do not use Split(char,int) as that one
// does not exist on .NET CF
string[] temp = s.Split(delimiter);
int counter = temp.Length < resultsPerLine ? temp.Length : resultsPerLine;
for (int i = 0; i < counter; i++)
{
this.elements[size++] = temp[i];
}
for (int i = resultsPerLine; i < temp.Length; i++)
{
this.elements[size - 1] += delimiter + temp[i];
}
}
}
else
{
string[] temp = source.Split(delimiter);
resultsPerLine = temp.Length < resultsPerLine ? temp.Length : resultsPerLine;
this.elements = new string[resultsPerLine];
for (int i = 0; i < resultsPerLine; i++)
{
this.elements[i] = temp[i];
}
for (int i = resultsPerLine; i < temp.Length; i++)
{
this.elements[resultsPerLine - 1] += delimiter + temp[i];
}
}
}
}
/// <summary>IEnumerable Interface Implementation, for the noninterface</summary>
public TokenEnumerator GetEnumerator() // non-IEnumerable version
{
return new TokenEnumerator(this);
}
/// <summary>IEnumerable Interface Implementation</summary>
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator)new TokenEnumerator(this);
}
/// <summary>Inner class implements IEnumerator interface</summary>
public class TokenEnumerator : IEnumerator
{
private int position = -1;
private TokenCollection tokens;
/// <summary>Standard constructor</summary>
public TokenEnumerator(TokenCollection tokens)
{
this.tokens = tokens;
}
/// <summary>IEnumerable::MoveNext implementation</summary>
public bool MoveNext()
{
if (this.tokens.elements != null && position < this.tokens.elements.Length - 1)
{
position++;
return true;
}
else
{
return false;
}
}
/// <summary>IEnumerable::Reset implementation</summary>
public void Reset()
{
position = -1;
}
/// <summary>Current implementation, non interface, type-safe</summary>
public string Current
{
get
{
return this.tokens.elements != null ? this.tokens.elements[position] : null;
}
}
/// <summary>Current implementation, interface, not type-safe</summary>
object IEnumerator.Current
{
get
{
return this.tokens.elements != null ? this.tokens.elements[position] : null;
}
}
}
static public string FindToken(TokenCollection tokens, string key)
{
string returnValue = null;
bool fNextOne = false;
foreach (string token in tokens)
{
if (fNextOne == true)
{
returnValue = token;
break;
}
if (key == token)
{
// next one is it
fNextOne = true;
}
}
return returnValue;
}
}
}
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
namespace WindowsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
WebRequest req = WebRequest.Create("https://www.google.com/accounts/ClientLogin");
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
Stream stream = req.GetRequestStream();
StreamWriter streamWriter = new StreamWriter(stream, Encoding.ASCII);
streamWriter.Write("accountType=HOSTED_OR_GOOGLE");
streamWriter.Write("&Email=binwind1984@gmail.com");//帐号换成你自己的
streamWriter.Write("&Passwd=XXX");//密码换成你自己的
streamWriter.Write("&service=lh2");
streamWriter.Write("&source=bin-test-1.0");
streamWriter.Close();
stream.Close();
WebResponse rep = req.GetResponse();
Stream responseStream = rep.GetResponseStream();
StreamReader responseReader = new StreamReader(responseStream, Encoding.ASCII);
string a = responseReader.ReadToEnd();
TokenCollection tokens = new TokenCollection(a, '=', true, 2);
string token = TokenCollection.FindToken(tokens, "Auth");
responseReader.Close();
responseStream.Close();
req = WebRequest.Create("http://picasaweb.google.com/data/feed/api/user/binwind1984/album/UntitledAlbum");
//binwind1984替换为相应的帐号,UntitledAlbum替换为相应的相册名字
string boundry = "-----xxxxxxxBOUNDERxxxxdxx";
req.ContentType = "multipart/related; boundary="" + boundry + """;
//req.ContentType = "image/jpeg";
HttpWebRequest httpReq = req as HttpWebRequest;
httpReq.AllowAutoRedirect = false;
req.Method = "POST";
req.Headers.Add("Authorization: GoogleLogin auth=" + token);
req.Headers.Add("MIME-version: 1.0");
stream = req.GetRequestStream();
streamWriter = new StreamWriter(stream, Encoding.ASCII);
streamWriter.WriteLine("Media multipart posting");
streamWriter.Write("--" + boundry + " ");
streamWriter.Write("Content-Type: application/atom+xml ");
//streamWriter.WriteLine("<?xml version='1.0' encoding='UTF-8'?>");
streamWriter.WriteLine("<entry xmlns="http://www.w3.org/2005/Atom">");
streamWriter.WriteLine("<title>test document</title>");
streamWriter.WriteLine("<summary>Darcy on the beach</summary>");
streamWriter.WriteLine("<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/photos/2007#photo"/>");
streamWriter.WriteLine("</entry>");
streamWriter.Write("--" + boundry + " ");
streamWriter.Write("Content-Type: image/jpeg ");
streamWriter.Flush();
FileStream fs = new FileStream("C:/s.jpg", FileMode.Open);//这里假设上传c:s.jpg文件.
byte[] bytes = new byte[1024];
while (fs.CanRead)
{
int read = fs.Read(bytes, 0, 1024);
stream.Write(bytes, 0, read);
if (read == 0)
{
break;
}
}
fs.Close();
stream.Flush();
streamWriter.Write("--" + boundry + "--" + " ");
streamWriter.Close();
stream.Close();
try
{
rep = req.GetResponse();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
public class TokenCollection : IEnumerable
{
private string[] elements;
/// <summary>Constructor, takes a string and a delimiter set</summary>
public TokenCollection(string source, char[] delimiters)
{
if (source != null)
{
this.elements = source.Split(delimiters);
}
}
/// <summary>Constructor, takes a string and a delimiter set</summary>
public TokenCollection(string source, char delimiter,
bool seperateLines, int resultsPerLine)
{
if (source != null)
{
if (seperateLines == true)
{
// first split the source into a line array
string[] lines = source.Split(new char[] { ' ' });
int size = lines.Length * resultsPerLine;
this.elements = new string[size];
size = 0;
foreach (String s in lines)
{
// do not use Split(char,int) as that one
// does not exist on .NET CF
string[] temp = s.Split(delimiter);
int counter = temp.Length < resultsPerLine ? temp.Length : resultsPerLine;
for (int i = 0; i < counter; i++)
{
this.elements[size++] = temp[i];
}
for (int i = resultsPerLine; i < temp.Length; i++)
{
this.elements[size - 1] += delimiter + temp[i];
}
}
}
else
{
string[] temp = source.Split(delimiter);
resultsPerLine = temp.Length < resultsPerLine ? temp.Length : resultsPerLine;
this.elements = new string[resultsPerLine];
for (int i = 0; i < resultsPerLine; i++)
{
this.elements[i] = temp[i];
}
for (int i = resultsPerLine; i < temp.Length; i++)
{
this.elements[resultsPerLine - 1] += delimiter + temp[i];
}
}
}
}
/// <summary>IEnumerable Interface Implementation, for the noninterface</summary>
public TokenEnumerator GetEnumerator() // non-IEnumerable version
{
return new TokenEnumerator(this);
}
/// <summary>IEnumerable Interface Implementation</summary>
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator)new TokenEnumerator(this);
}
/// <summary>Inner class implements IEnumerator interface</summary>
public class TokenEnumerator : IEnumerator
{
private int position = -1;
private TokenCollection tokens;
/// <summary>Standard constructor</summary>
public TokenEnumerator(TokenCollection tokens)
{
this.tokens = tokens;
}
/// <summary>IEnumerable::MoveNext implementation</summary>
public bool MoveNext()
{
if (this.tokens.elements != null && position < this.tokens.elements.Length - 1)
{
position++;
return true;
}
else
{
return false;
}
}
/// <summary>IEnumerable::Reset implementation</summary>
public void Reset()
{
position = -1;
}
/// <summary>Current implementation, non interface, type-safe</summary>
public string Current
{
get
{
return this.tokens.elements != null ? this.tokens.elements[position] : null;
}
}
/// <summary>Current implementation, interface, not type-safe</summary>
object IEnumerator.Current
{
get
{
return this.tokens.elements != null ? this.tokens.elements[position] : null;
}
}
}
static public string FindToken(TokenCollection tokens, string key)
{
string returnValue = null;
bool fNextOne = false;
foreach (string token in tokens)
{
if (fNextOne == true)
{
returnValue = token;
break;
}
if (key == token)
{
// next one is it
fNextOne = true;
}
}
return returnValue;
}
}
}
谈谈那我参考的一些文档:
Writing C# code for a multipart file upload to a Java servlet : http://blog.mindbridge.com/?p=59