使用C#调用Java带MIME附件WebService方法的初步设想
朋友说开发电信的MMS,其实需要图片作为附件放在调用WebService接口上,使用Http的Content-Type: Multipart/Related;来发送,真让人感觉不伦不类的。不知道为什么不设计成一个字段是BASE64编码得了呗。
难道只能用朋友说的拼字段的方法了不? 我用Reflect分析了一下,貌似这样也可以实现。
我们知道,我们添加一个WebService引用时,会自动生成从 SoapHttpClientProtocol 的子类。我的想法是,我们写一个 继承自"SoapHttpClientProtocol” 的子类SoapHttpClientProtocolEX, 重写方法:GetWebRequest() 返回我们写的代码 HttpWebRequestEx类,然后在原始 HttpWebRequest 类的GetRequestStream()时,返回我们的流转移器:NetwordStreamEx ,并在方法关闭流 Close() 前,加入自定义的附件信息。
不知道说清楚没有, 这里列了部分代码框架:
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; } } public override void Flush() { baseStream.Flush(); } public override long Length { get { return baseStream.Length; } } public override long Position { get { return baseStream.Position; } set { baseStream.Position = value; } } public override int Read(byte[] buffer, int offset, int count) { return baseStream.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { return baseStream.Seek(offset, origin); } public override void SetLength(long value) { baseStream.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { baseStream.Write(buffer, offset, count); } #endregion } }
引自:51aspx
QQ:273352165
evlon#126.com
转载请注明出处。