Step 0. 下载 ICSharpCode.SharpZipLib.dll
Step 1. 扩展 System.Web.Services.Protocols.SoapExtension,代码如下:

Code
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Core;
namespace SoapCompressionExtension
{
public class CompressionSoapExtensionCore : SoapExtension
{
Stream oldStream;
Stream newStream;
//必须重载的方法
public override Stream ChainStream(Stream stream)
{
oldStream = stream;
newStream = new MemoryStream();
return newStream;
}
//必须重载的方法
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
return null;
}
//必须重载的方法
public override object GetInitializer(Type WebServiceType)
{
return null;
}
//必须重载的方法
public override void Initialize(object initializer){}
//必须重载的方法
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize:
break;
case SoapMessageStage.AfterSerialize:
//压缩
Compress(message);
break;
case SoapMessageStage.BeforeDeserialize:
//解压缩
Decompress(message);
break;
case SoapMessageStage.AfterDeserialize:
break;
default:
throw new Exception("invalid stage");
}
}
private void Compress(SoapMessage message)
{
using (GZipOutputStream gzip = new GZipOutputStream(oldStream))
{
message.Stream.Position = 0;
StreamUtils.Copy(message.Stream, gzip, new byte[4096]);
}
}
private void Decompress(SoapMessage message)
{
using (Stream s = new GZipInputStream(oldStream))
{
StreamUtils.Copy(s, message.Stream, new byte[4096]);
}
message.Stream.Position = 0;
}
}
}
Step 2. 配置Web Service,拷贝以下配置代码到<system.web></system.web>
<webServices>
<soapExtensionTypes>
<add type="SoapCompressionExtension.CompressionSoapExtensionCore,SoapCompressionExtension" priority="3" group="0"/>
</soapExtensionTypes>
</webServices>
Step 3. 配置客户端
1) WinForm 程序配置方法: 拷贝以下代码到app.config的<configuration></configuration>节点内。
<system.web>
<webServices>
<soapExtensionTypes>
<add type="SoapCompressionExtension.CompressionSoapExtensionCore,SoapCompressionExtension" priority="3" group="0"/>
</soapExtensionTypes>
</webServices>
</system.web>
2) Asp.net 程序配置方法: 拷贝以下配置代码到web.config的<system.web></system.web>节点内。
<webServices>
<soapExtensionTypes>
<add type="SoapCompressionExtension.CompressionSoapExtensionCore,SoapCompressionExtension" priority="0" group="0"/>
</soapExtensionTypes>
</webServices>
flickr要求的POST格式是 multipart/form-datafa (格式范例),而.NET的HttpWebRequest类,只能POST标准的 application/x-www-form-urlencoded, 所以我们只能手工将数据打包成 multipart/form-datafa ,我参考了Python的例子,写了一版C#的,代码如下:
1 public static string HttpPostByMultipartFormData(string url, List<FormField> fields,string filefieldname,string filename,Stream filestream)
2 {
3 HttpWebResponse response = null;
4 Stream strm = null;
5 StreamReader sr = null;
6
7 try
8 {
9 string Boundary = "--------------------------------ThIs_Is_tHe_bouNdaRY_$";
10 string CRLF = "\r\n";
11
12 string body = "";
13
14 foreach (FormField field in fields)
15 {
16 body += "--" + Boundary;
17 body += CRLF;
18 body += "Content-Disposition: form-data; name=\"" + field.Key + "\"";
19 body += CRLF+CRLF;
20 body += field.Value;
21 body += CRLF;
22 }
23
24 body += "--" + Boundary;
25 body += CRLF;
26 body += "Content-Disposition: form-data; name=\"" + filefieldname + "\"; filename=\"" + filename + "\"";
27 body += CRLF;
28 body += "Content-Type: " + GetContentType(filename);
29 body += CRLF+CRLF;
30
31 byte[] buf1 = System.Text.Encoding.UTF8.GetBytes(body);
32 byte[] buf2 = new byte[filestream.Length];
33 filestream.Read(buf2, 0, (int)filestream.Length);
34 filestream.Close();
35
36 byte[] buf3 = new byte[buf1.Length + buf2.Length];
37 Array.Copy(buf1,0,buf3,0,buf1.Length);
38 Array.Copy(buf2,0,buf3,buf1.Length,buf2.Length);
39
40
41 string end = CRLF+"--" + Boundary + "--"+CRLF;
42 buf1 = System.Text.Encoding.UTF8.GetBytes(end);
43 buf2 = new byte[buf1.Length + buf3.Length];
44 Array.Copy(buf3, 0, buf2, 0, buf3.Length);
45 Array.Copy(buf1, 0, buf2, buf3.Length, buf1.Length);
46
47
48 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
49
50 request.Method = "POST";
51 request.ContentLength = buf2.Length;
52 request.ContentType = "multipart/form-data; boundary=" + Boundary;//"application/x-www-form-urlencoded";
53
54 strm = request.GetRequestStream();
55 strm.Write(buf2, 0, buf2.Length);
56 strm.Close();
57
58
59
60 response = request.GetResponse() as HttpWebResponse;
61 strm = response.GetResponseStream();
62 sr = new StreamReader(strm);
63 string strXML = sr.ReadToEnd();
64 sr.Close();
65
66 strm.Close();
67 response.Close();
68
69 return strXML;
70
71 }
72 catch
73 {
74
75 if (sr != null)
76 {
77 sr.Close();
78 }
79
80 if (strm != null)
81 { strm.Close(); }
82
83 if (response != null)
84 { response.Close(); }
85
86 return null;
87 }
88
89 }