现在的位置: 首页 > 综合 > 正文

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

2013年09月09日 ⁄ 综合 ⁄ 共 6269字 ⁄ 字号 评论关闭

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});
  }
 }

抱歉!评论已关闭.