您的位置:首页 > 其它

一个用于.NET下动态添加Web引用的简单class

2006-04-13 22:48 471 查看
WssDataProvider中用到的一个动态添加Web引用的类,接口不算完整,不过算是大概够用了。这里要提醒一下各位:动态添加需要花费不少时间的,不到万不得已,大家还是老老实实的用静态添加吧^&^

/// <summary>
/// Represents a web reference to connect with web service.
/// this class can be used only in WssDataProvider assembly
/// </summary>
public class WebReference
{
private Assembly _assembly = null;
private string _asmUrl = String.Empty;
private string _asmNameSpace = String.Empty;
private string _url = String.Empty;
private string _nameSpace = String.Empty;
private string _className = String.Empty;
private string _methodName = String.Empty;

private WebProxy _proxy = null;
private NetworkCredential _credential = null;

/// <summary>
/// default constructor
/// </summary>
public WebReference()
{
}

// overload constructor
public WebReference(string url, string nameSpace, string className)
{
_url = url;
_nameSpace = nameSpace;
_className = className;
}

public WebReference(string url, string nameSpace, string className, NetworkCredential credential, WebProxy proxy)
{
_url = url;
_nameSpace = nameSpace;
_className = className;
_credential = credential;
_proxy = proxy;
}

/// <summary>
/// get and set web proxy
/// </summary>
public WebProxy Proxy
{
get { return _proxy; }
set { _proxy = value; }
}

/// <summary>
/// get and set web credential
/// </summary>
public NetworkCredential Credential
{
get { return _credential; }
set { _credential = value; }
}

/// <summary>
/// get and set url of SharePoint Web service to be connected
/// </summary>
public string Url
{
get { return _url; }
set { _url = value; }
}

/// <summary>
/// get and set namespace of SharePoint Web Service to be connected
/// </summary>
public string Namespace
{
get { return _nameSpace; }
set { _nameSpace = value; }
}

/// <summary>
/// Create a new web reference assembly that proxy the web service
/// </summary>
/// <param name="url">url of SharePoint Web service to be connected</param>
/// <param name="nameSpace">namespace of SharePoint Web service to be connected</param>
/// <returns>Compiled assembly, here it can be considered as a cache to improve the performance</returns>
public Assembly CreateNewAssembly(string url, string nameSpace)
{
try
{
WebClient wc = new WebClient();
Stream stream = wc.OpenRead(url + "?WSDL");
ServiceDescription sd = ServiceDescription.Read(stream);
ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
sdi.AddServiceDescription(sd, "", "");
CodeNamespace cn = new CodeNamespace(@nameSpace);
CodeCompileUnit ccu = new CodeCompileUnit();
ccu.Namespaces.Add(cn);
sdi.Import(cn, ccu);

CSharpCodeProvider csc = new CSharpCodeProvider();
ICodeCompiler icc = csc.CreateCompiler();

CompilerParameters cplist = new CompilerParameters();
cplist.GenerateExecutable = false;
cplist.GenerateInMemory = true;
cplist.ReferencedAssemblies.Add("System.dll");
cplist.ReferencedAssemblies.Add("System.XML.dll");
cplist.ReferencedAssemblies.Add("System.Web.Services.dll");
cplist.ReferencedAssemblies.Add("System.Data.dll");

CompilerResults cr = icc.CompileAssemblyFromDom(cplist, ccu);
if (true == cr.Errors.HasErrors)
{
StringBuilder sb = new StringBuilder();
foreach (CompilerError ce in cr.Errors)
{
sb.Append(ce.ToString());
sb.Append(Environment.NewLine);
}
throw new Exception(sb.ToString());
}

this._asmUrl = this.Url;
this._asmNameSpace = this.Namespace;

this._assembly = cr.CompiledAssembly;

return this._assembly;
}
catch (Exception ex)
{
throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace));
}
}

/// <summary>
/// public interface to call a SharePoint Webservice WebMethod
/// </summary>
/// <param name="methodName">name of web method to be called</param>
/// <param name="paramArgs">web mathod's parameters to be passed to server</param>
/// <returns>returned value from SharePoint Web Service</returns>
public object InvokeWebMethod(string methodName, object[] paramArgs)
{
try
{
//if(this.Url != this._asmUrl || this.Namespace != this._nameSpace)
//{
if (_assembly == null)
this._assembly = CreateNewAssembly(this.Url, this.Namespace);
//}

Type type = _assembly.GetType(@_nameSpace + "." + _className, true, true);
object obj = Activator.CreateInstance(type);

((SoapHttpClientProtocol) obj).Proxy = this.Proxy;
((WebClientProtocol) obj).Credentials = this.Credential;

MethodInfo mi = type.GetMethod(methodName);

return mi.Invoke(obj, paramArgs);
}
catch (Exception ex)
{
throw new Exception(ex.InnerException.Message, new Exception(ex.InnerException.StackTrace));
}
}

/// <summary>
/// Begin invoking remote web method in asynchronism mechanism
/// </summary>
/// <param name="methodName">Name of method which you want to invoke</param>
/// <param name="paramArgs">Parameter array required by the method definition</param>
/// <param name="callback">Call back method for the asynchronism invoke</param>
/// <param name="asyncState">Represents the state for asynchronism invoke</param>
/// <returns>An IAsyncResult</returns>
public IAsyncResult BeginInvokeWebMethod(string methodName, object[] paramArgs, AsyncCallback callback, object asyncState)
{
try
{
_methodName = methodName;

if (_assembly == null)
{
this._assembly = CreateNewAssembly(this.Url, this.Namespace);
}

Type type = _assembly.GetType(@_nameSpace + "." + _className, true, true);
object obj = Activator.CreateInstance(type);

((SoapHttpClientProtocol) obj).Proxy = this.Proxy;
((WebClientProtocol) obj).Credentials = this.Credential;

MethodInfo mi = type.GetMethod("Begin" + methodName);

// construct a new Array for Begin Invoke
int length = paramArgs.GetLength(0) + 2;
object[] parameters = new object[length];
paramArgs.CopyTo(parameters, 0);
parameters[paramArgs.GetLength(0)] = callback;
parameters[paramArgs.GetLength(0) + 1] = asyncState;

return mi.Invoke(obj, parameters) as IAsyncResult;
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
}

/// <summary>
/// Callback methods for invoking web service in asynchronism mechanism
/// </summary>
/// <param name="asyncResult">The IAsyncResult required by the EndXXX method</param>
/// <returns>Returned value by the remote web service</returns>
public object EndInvokeWebMethod(IAsyncResult asyncResult)
{
Type type = _assembly.GetType(@_nameSpace + "." + _className, true, true);
object obj = Activator.CreateInstance(type);

((SoapHttpClientProtocol) obj).Proxy = this.Proxy;
((WebClientProtocol) obj).Credentials = this.Credential;

MethodInfo mi = type.GetMethod("End" + _methodName);

return mi.Invoke(obj, new object[] {asyncResult});
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐