using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace YourNameSpace
{
public static class SoapHelper
{
private const string FORMAT_ENVELOPE = @"
<{0} xmlns='{1}'>{2}{0}>
";
private const string FORMAT_PARAMTER = "<{0}>{1}{0}>";
public static string MakeEnvelope(string soapAction, params SoapParameter[] soapParamters)
{
string nameSpace, methodName;
GetNameSpaceAndMethodName(soapAction, out nameSpace, out methodName);
string parameters = BuildSoapParameters(soapParamters);
return string.Format(FORMAT_ENVELOPE, methodName, nameSpace, parameters);
}
private static void GetNameSpaceAndMethodName(string soapAction, out string nameSpace, out string methodName)
{
var index = soapAction.LastIndexOf(Path.AltDirectorySeparatorChar);
nameSpace = soapAction.Substring(0, index + 1);
methodName = soapAction.Substring(index + 1, soapAction.Length - index - 1);
}
private static string BuildSoapParameters(IEnumerable parameters)
{
var sb = new StringBuilder();
foreach (var param in parameters)
{
string content = GetObjectContent(param.Value);
sb.AppendFormat(FORMAT_PARAMTER, param.Name, content);
}
return sb.ToString();
}
private static String GetObjectContent(Object graph)
{
using (var memoryStream = new MemoryStream())
{
var graphType = graph.GetType();
var xmlSerializer = new XmlSerializer(graphType);
xmlSerializer.Serialize(memoryStream, graph);
var strContent = Encoding.UTF8.GetString(memoryStream.ToArray());
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(strContent);
if (graphType.IsGenericType && graphType.GetGenericTypeDefinition() == typeof(List<>))
{
Type itemType = graphType.GetGenericArguments()[0];
string graphName = "ArrayOf" + itemType.Name;
XmlNode contentNode = xmlDocument.SelectSingleNode(graphName);
if (contentNode != null)
return contentNode.InnerXml;
}
if (graphType.Name == "String[]")
{
String[] contents = (String[])graph;
string content = "";
foreach (var c in contents)
{
content = content + "" + c + "";
}
if (content != "")
return content;
}
else
{
XmlNode contentNode;
if (graphType.Name == "Byte[]")
contentNode = xmlDocument.SelectSingleNode("base64Binary");
else
contentNode = xmlDocument.SelectSingleNode(graphType.Name);
if (contentNode != null)
return contentNode.InnerXml;
}
return graph.ToString();
}
}
}
public sealed class SoapParameter
{
public string Name { get; set; }
public object Value { get; set; }
public SoapParameter(string name, object value)
{
this.Name = name;
this.Value = value;
}
}
public sealed class SoapClient
{
public Uri Uri { get; set; }
public string SoapAction { get; set; }
public IList Arguments { get; private set; }
public ICredentials Credentials { get; set; }
public SoapClient(string uriString, string soapAction)
{
this.Uri = new Uri(uriString);
this.SoapAction = soapAction;
this.Arguments = new List();
this.Credentials = CredentialCache.DefaultNetworkCredentials;
}
private WebResponse GetResponse()
{
var webRequest = (HttpWebRequest)WebRequest.Create(this.Uri);
webRequest.Headers.Add("SOAPAction", string.Format("\"{0}\"", this.SoapAction));
webRequest.ContentType = "text/xml;charset=utf-8";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
webRequest.Credentials = this.Credentials;
string envelope = SoapHelper.MakeEnvelope(this.SoapAction, this.Arguments.ToArray())
.Replace("\r", "").Replace("\n", "").Trim();
byte[] bytes = Encoding.UTF8.GetBytes(envelope);
Stream requestStream = webRequest.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();
WebResponse webResponse = null;
try
{
webResponse = webRequest.GetResponse();
}
catch (WebException ex)
{
Console.WriteLine("Exception: " + new StreamReader(ex.Response.GetResponseStream()).ReadToEnd());
}
return webResponse;
}
public string GetResult()
{
var webResponse = this.GetResponse();
if (webResponse == null)
return "null";
Stream responseStream = webResponse.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
return reader.ReadToEnd();
}
}
}