朋友说开发电信的MMS,其实需要图片作为附件放在调用WebService接口上,使用Http的Content-Type: Multipart/Related;来发送,真让人感觉不伦不类的。不知道为什么不设计成一个字段是BASE64编码得了呗。
难道只能用朋友说的拼字段的方法了不? 我用Reflect分析了一下,貌似这样也可以实现。
我们知道,我们添加一个WebService引用时,会自动生成从 SoapHttpClientProtocol 的子类。我的想法是,我们写一个 继承自"SoapHttpClientProtocol” 的子类SoapHttpClientProtocolEX, 重写方法:GetWebRequest() 返回我们写的代码 HttpWebRequestEx类,然后在原始 HttpWebRequest 类的GetRequestStream()时,返回我们的流转移器:NetwordStreamEx ,并在方法关闭流 Close() 前,加入自定义的附件信息。
不知道说清楚没有, 这里列了部分代码框架:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![ExpandedBlockStart.gif](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
using
System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Services.Protocols;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace Foundway.Util.WebService
{
public class SoapHttpClientProtocolEx : SoapHttpClientProtocol
{
private List < string > attachments = new List < string > ();
/// <summary>
/// 添加一个附件
/// </summary>
/// <param name="attachment"> 附件全路径 </param>
public void AddAttachment( string attachment)
{
attachments.Add(attachment);
}
protected override WebRequest GetWebRequest(Uri uri)
{
WebRequest request = base .GetWebRequest(uri);
if (attachments.Count > 0 )
{
HttpWebRequest httpRequest = request as HttpWebRequest;
if (httpRequest != null )
{
httpRequest.SendChunked = true ; // 使用多段发送
HttpWebRequestEx httpRequestEx = new HttpWebRequestEx(httpRequest, attachments.ToArray());
return httpRequestEx;
}
}
return request;
}
}
public class HttpWebRequestEx : WebRequest
{
private string [] attachments;
private HttpWebRequest httpRequest = null ;
public HttpWebRequestEx(HttpWebRequest httpRequest, string [] attachments)
{
this .httpRequest = httpRequest;
this .attachments = attachments;
}
public override System.IO.Stream GetRequestStream()
{
Stream stream = httpRequest.GetRequestStream();
// 返回自定义的流代理,来完成附件的信息
return new NetworkStreamEx(stream, this .attachments);
}
#region 重写其它全部公共方法
public override void Abort()
{
httpRequest.Abort();
}
public override IAsyncResult BeginGetRequestStream(AsyncCallback callback, object state)
{
return httpRequest.BeginGetRequestStream(callback, state);
}
public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state)
{
return httpRequest.BeginGetResponse(callback, state);
}
public override System.Net.Cache.RequestCachePolicy CachePolicy
{
get
{
return httpRequest.CachePolicy;
}
set
{
httpRequest.CachePolicy = value;
}
}
public override string ConnectionGroupName
{
get
{
return httpRequest.ConnectionGroupName;
}
set
{
httpRequest.ConnectionGroupName = value;
}
}
public override long ContentLength
{
get
{
return httpRequest.ContentLength;
}
set
{
httpRequest.ContentLength = value;
}
}
public override string ContentType
{
get
{
return httpRequest.ContentType;
}
set
{
httpRequest.ContentType = value;
}
}
public override System.Runtime.Remoting.ObjRef CreateObjRef(Type requestedType)
{
return httpRequest.CreateObjRef(requestedType);
}
public override ICredentials Credentials
{
get
{
return httpRequest.Credentials;
}
set
{
httpRequest.Credentials = value;
}
}
public override Stream EndGetRequestStream(IAsyncResult asyncResult)
{
return httpRequest.EndGetRequestStream(asyncResult);
}
public override WebResponse EndGetResponse(IAsyncResult asyncResult)
{
return httpRequest.EndGetResponse(asyncResult);
}
public override WebResponse GetResponse()
{
return httpRequest.GetResponse();
}
public override WebHeaderCollection Headers
{
get
{
return httpRequest.Headers;
}
set
{
httpRequest.Headers = value;
}
}
public override string Method
{
get
{
return httpRequest.Method;
}
set
{
httpRequest.Method = value;
}
}
public override bool PreAuthenticate
{
get
{
return httpRequest.PreAuthenticate;
}
set
{
httpRequest.PreAuthenticate = value;
}
}
public override IWebProxy Proxy
{
get
{
return httpRequest.Proxy;
}
set
{
httpRequest.Proxy = value;
}
}
public override object InitializeLifetimeService()
{
return httpRequest.InitializeLifetimeService();
}
public override Uri RequestUri
{
get
{
return httpRequest.RequestUri;
}
}
public override int Timeout
{
get
{
return httpRequest.Timeout;
}
set
{
httpRequest.Timeout = value;
}
}
public override string ToString()
{
return httpRequest.ToString();
}
public override bool UseDefaultCredentials
{
get
{
return httpRequest.UseDefaultCredentials;
}
set
{
httpRequest.UseDefaultCredentials = value;
}
}
public override bool Equals( object obj)
{
return httpRequest.Equals(obj);
}
public override int GetHashCode()
{
return httpRequest.GetHashCode();
}
#endregion
}
public class NetworkStreamEx :Stream
{
private string [] attachments;
private Stream baseStream;
public NetworkStreamEx(Stream baseStream, string [] attachments)
{
this .baseStream = baseStream;
}
/// <summary>
/// 在关闭时,加入附件信息
/// </summary>
public override void Close()
{
/// TODO:这里添加附件信息,
/// 这里就不加代码了
///
base .Close();
}
#region 把其它公共方法转发到原流
public override bool CanRead
{
get { return baseStream.CanRead; }
}
public override bool CanSeek
{
get { return baseStream.CanSeek; }
}
public override bool CanWrite
{
get { return baseStream.CanWrite; }
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Services.Protocols;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace Foundway.Util.WebService
{
public class SoapHttpClientProtocolEx : SoapHttpClientProtocol
{
private List < string > attachments = new List < string > ();
/// <summary>
/// 添加一个附件
/// </summary>
/// <param name="attachment"> 附件全路径 </param>
public void AddAttachment( string attachment)
{
attachments.Add(attachment);
}
protected override WebRequest GetWebRequest(Uri uri)
{
WebRequest request = base .GetWebRequest(uri);
if (attachments.Count > 0 )
{
HttpWebRequest httpRequest = request as HttpWebRequest;
if (httpRequest != null )
{
httpRequest.SendChunked = true ; // 使用多段发送
HttpWebRequestEx httpRequestEx = new HttpWebRequestEx(httpRequest, attachments.ToArray());
return httpRequestEx;
}
}
return request;
}
}
public class HttpWebRequestEx : WebRequest
{
private string [] attachments;
private HttpWebRequest httpRequest = null ;
public HttpWebRequestEx(HttpWebRequest httpRequest, string [] attachments)
{
this .httpRequest = httpRequest;
this .attachments = attachments;
}
public override System.IO.Stream GetRequestStream()
{
Stream stream = httpRequest.GetRequestStream();
// 返回自定义的流代理,来完成附件的信息
return new NetworkStreamEx(stream, this .attachments);
}
#region 重写其它全部公共方法
public override void Abort()
{
httpRequest.Abort();
}
public override IAsyncResult BeginGetRequestStream(AsyncCallback callback, object state)
{
return httpRequest.BeginGetRequestStream(callback, state);
}
public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state)
{
return httpRequest.BeginGetResponse(callback, state);
}
public override System.Net.Cache.RequestCachePolicy CachePolicy
{
get
{
return httpRequest.CachePolicy;
}
set
{
httpRequest.CachePolicy = value;
}
}
public override string ConnectionGroupName
{
get
{
return httpRequest.ConnectionGroupName;
}
set
{
httpRequest.ConnectionGroupName = value;
}
}
public override long ContentLength
{
get
{
return httpRequest.ContentLength;
}
set
{
httpRequest.ContentLength = value;
}
}
public override string ContentType
{
get
{
return httpRequest.ContentType;
}
set
{
httpRequest.ContentType = value;
}
}
public override System.Runtime.Remoting.ObjRef CreateObjRef(Type requestedType)
{
return httpRequest.CreateObjRef(requestedType);
}
public override ICredentials Credentials
{
get
{
return httpRequest.Credentials;
}
set
{
httpRequest.Credentials = value;
}
}
public override Stream EndGetRequestStream(IAsyncResult asyncResult)
{
return httpRequest.EndGetRequestStream(asyncResult);
}
public override WebResponse EndGetResponse(IAsyncResult asyncResult)
{
return httpRequest.EndGetResponse(asyncResult);
}
public override WebResponse GetResponse()
{
return httpRequest.GetResponse();
}
public override WebHeaderCollection Headers
{
get
{
return httpRequest.Headers;
}
set
{
httpRequest.Headers = value;
}
}
public override string Method
{
get
{
return httpRequest.Method;
}
set
{
httpRequest.Method = value;
}
}
public override bool PreAuthenticate
{
get
{
return httpRequest.PreAuthenticate;
}
set
{
httpRequest.PreAuthenticate = value;
}
}
public override IWebProxy Proxy
{
get
{
return httpRequest.Proxy;
}
set
{
httpRequest.Proxy = value;
}
}
public override object InitializeLifetimeService()
{
return httpRequest.InitializeLifetimeService();
}
public override Uri RequestUri
{
get
{
return httpRequest.RequestUri;
}
}
public override int Timeout
{
get
{
return httpRequest.Timeout;
}
set
{
httpRequest.Timeout = value;
}
}
public override string ToString()
{
return httpRequest.ToString();
}
public override bool UseDefaultCredentials
{
get
{
return httpRequest.UseDefaultCredentials;
}
set
{
httpRequest.UseDefaultCredentials = value;
}
}
public override bool Equals( object obj)
{
return httpRequest.Equals(obj);
}
public override int GetHashCode()
{
return httpRequest.GetHashCode();
}
#endregion
}
public class NetworkStreamEx :Stream
{
private string [] attachments;
private Stream baseStream;
public NetworkStreamEx(Stream baseStream, string [] attachments)
{
this .baseStream = baseStream;
}
/// <summary>
/// 在关闭时,加入附件信息
/// </summary>
public override void Close()
{
/// TODO:这里添加附件信息,
/// 这里就不加代码了
///
base .Close();
}
#region 把其它公共方法转发到原流
public override bool CanRead
{
get { return baseStream.CanRead; }
}
public override bool CanSeek
{
get { return baseStream.CanSeek; }
}
public override bool CanWrite
{
get { return baseStream.CanWrite; }
}