. net webclient calls webservice

Time:2021-2-10

Calling WebService by webclient

(download the complete code at the end of the article)

First code:

      object[] inObjects = new[] { "14630, 14631" };
      HttpWebClient wc = new HttpWebClient(2300);
      var result1 = WebServiceClientHelper.InvokeWebService("ESBService_TEST", "http://localhost/ESBService/VitalSign.svc?wsdl", "QueryVocabSet", inObjects, wc);
      WriteLine(result1.ToString());
public class HttpWebClient : WebClient
    {
        /// 
        ///Initialization needs to set the timeout in milliseconds
        /// 
        ///In milliseconds
        public HttpWebClient(int timeout)
        {
            Timeout = timeout;
        }

        public int Timeout { get; set; }

        /// 
        ///Rewrite getwebrequest, add webrequest object timeout
        /// 
        protected override WebRequest GetWebRequest(Uri address)
        {
            HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
            request.Timeout = Timeout;
            request.ReadWriteTimeout = Timeout;
            return request;
        }
    }

Httpwebrequest transformation basis:

WebClient

HttpWebRequest

Provides common methods for sending data to and receiving data from a resource identified by a URI.

public class HttpWebRequest : WebRequest, ISerializable

Assembly location:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.dll

Assembly location:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.dll

protected virtual WebRequest GetWebRequest(Uri address)
    {
      WebRequest request = WebRequest.Create(address);
      this.CopyHeadersTo(request);
      if (this.Credentials != null)
        request.Credentials = this.Credentials;
      if (this.m_Method != null)
        request.Method = this.m_Method;
      if (this.m_ContentLength != -1L)
        request.ContentLength = this.m_ContentLength;
      if (this.m_ProxySet)
        request.Proxy = this.m_Proxy;
      if (this.m_CachePolicy != null)
        request.CachePolicy = this.m_CachePolicy;
      return request;
    }

    protected virtual WebResponse GetWebResponse(WebRequest request)
    {
      WebResponse response = request.GetResponse();
      this.m_WebResponse = response;
      return response;
    }

 

 

public class HttpWebClient : WebClient
    {
        /// 
        ///Initialization needs to set the timeout in milliseconds
        /// 
        ///In milliseconds
        public HttpWebClient(int timeout)
        {
            Timeout = timeout;
        }

        public int Timeout { get; set; }

        /// 
        ///Rewrite getwebrequest, add webrequest object timeout
        /// 
        protected override WebRequest GetWebRequest(Uri address)
        {
            HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
            request.Timeout = Timeout;
            request.ReadWriteTimeout = Timeout;
            return request;
        }
    }

 

Call service processing:

        public static object InvokeWebService(string providerName, string url, string methodName, object[] args, WebClient wc = null)
        {
            object result = null;

            if (wc == null) wc = new WebClient();
            using (wc)
            {
                using (Stream wsdl = wc.OpenRead(url))
                {
                    var client = GetClient(wsdl, url, methodName, providerName);
                    client.SetValue("Timeout", wsdl.ReadTimeout);
                    result = client.InvokeService(args);
                }
            }

            return result;
        }

Like this http://192.168.2.100 : the address of 8090 / services / dutest? WSDL,

What is returned is the method exposed under dutest service in the form of stream,

In code processing, we need to interpret this stream. At present, one way we see is to interpret and compile this stream into a dynamic DLL, and use reflection to dynamically call methods.

. net webclient calls webservice. net webclient calls webservice

///Opens a readable stream for data downloaded from a resource with the specified URI.
    ///One for reading data from resources.
    ///The URI specified in the form, from which the data will be downloaded.
    public Stream OpenRead(string address)
    {
      if (address == null)
        throw new ArgumentNullException(nameof (address));
      return this.OpenRead(this.GetUri(address));
    }

    ///Opens a readable stream for data downloaded from a resource with the specified URI
    ///One for reading data from resources.
    ///The URI specified in the form, from which the data will be downloaded.
    public Stream OpenRead(Uri address)
    {
      if (Logging.On)
        Logging.Enter(Logging.Web, (object) this, nameof (OpenRead), (object) address);
      if (address == (Uri) null)
        throw new ArgumentNullException(nameof (address));
      WebRequest request = (WebRequest) null;
      this.ClearWebClientState();
      try
      {
        request = this.m_WebRequest = this.GetWebRequest(this.GetUri(address));
        Stream responseStream = (this.m_WebResponse = this.GetWebResponse(request)).GetResponseStream();
        if (Logging.On)
          Logging.Exit(Logging.Web, (object) this, nameof (OpenRead), (object) responseStream);
        return responseStream;
      }
      catch (Exception ex)
      {
        Exception innerException = ex;
        if (innerException is ThreadAbortException || innerException is StackOverflowException || innerException is OutOfMemoryException)
        {
          throw;
        }
        else
        {
          if (!(innerException is WebException) && !(innerException is SecurityException))
            innerException = (Exception) new WebException(SR.GetString("net_webclient"), innerException);
          WebClient.AbortRequest(request);
          throw innerException;
        }
      }
      finally
      {
        this.CompleteWebClientState();
      }
    }

View Code

Class defaultwebserviceclient definition:

. net webclient calls webservice. net webclient calls webservice

public class DefaultWebServiceClient
    {
        Type _type;
        MethodInfo _method;
        object _obj;

        public object InvokeService(object[] args)
        {
            object proxy = GetProxy();
            return _method.Invoke(proxy, args);
        }

        public void SetValue(string fieldName, object value)
        {
            object proxy = GetProxy();
            PropertyInfo field = _type.GetProperty(fieldName);
            if (field != null)
                field.SetValue(proxy, value);
        }

        public object GetProxy()
        {
            if (_obj == null)
                _obj = Activator.CreateInstance(_type);

            return _obj;
        }

        public MethodInfo MethodInfo
        {
            get { return _method; }
        }

        public DefaultWebServiceClient(Stream wsdl, string url, string methodname, string providerName)
        {
            if (wsdl == null || (wsdl.CanWrite && wsdl.Length == 0))
                Throw new exception ("WSDL is empty");

            try
            {
                ServiceDescription sd = ServiceDescription.Read(wsdl);
                ServiceDescriptionImporter sdi = new ServiceDescriptionImporter();
                sdi.AddServiceDescription(sd, "", "");
                CodeNamespace cn = new CodeNamespace(string.Format("DefaultWebServiceClient_{0}_{1}", providerName, wsdl.GetHashCode().ToString()));

                DiscoveryClientProtocol dcp = new DiscoveryClientProtocol();
                dcp.DiscoverAny(url);
                dcp.ResolveAll();
                foreach (object osd in dcp.Documents.Values)
                {
                    if (osd is ServiceDescription) sdi.AddServiceDescription((ServiceDescription)osd, null, null); ;
                    if (osd is XmlSchema) sdi.Schemas.Add((XmlSchema)osd);
                }

                //Generate client agent class code 
                CodeCompileUnit ccu = new CodeCompileUnit();
                ccu.Namespaces.Add(cn);
                sdi.Import(cn, ccu);
                CSharpCodeProvider csc = new CSharpCodeProvider();
                ICodeCompiler icc = csc.CreateCompiler();

                //Setting compiler parameters 
                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");

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

                //Generate the proxy instance and call the method 
                Assembly assembly = cr.CompiledAssembly;
                Type type = null;
                foreach (Type t in assembly.GetExportedTypes())
                {
                    if (t.GetCustomAttributes(typeof(System.Web.Services.WebServiceBindingAttribute), false).Count() > 0)
                    {
                        type = t;
                        break;
                    }
                }

                MethodInfo mi = null;

                if (type == null)
                {
                    Throw new exception ("no callable type found from WSDL");
                }

                mi = type.GetMethod(methodname);
                if (mi == null)
                {
                    throw new Exception( string.Format ("cannot find callable method {0}. {1} from WSDL"), type.Name , methodname));
                }
                _type = type;
                _method = mi;
            }
            catch (Exception ex)
            {
                Throw new exception ("failed to create WebService client! ", ex);
            }
        }
    }

View Code

Webclient is a type of operating webrequest, which is equivalent to a worker. It returns all the content (resources) provided by the server in the form of stream for us to call,

To interpret this kind of flow, you need an instance of the servicedescription class, and then load each item into the instance of the servicedescriptionimporter class,

Then compile it into a component that can be used locally and call it dynamically, which is equivalent to loading a DLL at runtime.

(Note: three methods call WebServicehttps://www.jb51.net/article/190211.htm

 

 

Validation 1

Validation 2

 

A new web client (service agent) is created,

The processing object of the request is webrequest by default,

Because webrequest has no timeout attribute, I inherit webclient, and override handles Httpwebrequest

(note that Httpwebrequest is a subclass of webrequest)

A new web client is created,

The processing object of the request is webrequest by default

 

result

During the whole call, Charles obtained two HTTP requests, among which:

The first time: when getting the WSDL stream, the request package is the get mode of HTTP request;

The second time: when the dynamic DLL reflection method is loaded, the request package is the post mode of HTTP request;

Same as left

card

Webclient is really a proxy, like a worker. In the code, it seems that it dynamically references the DLL of a third party locally, but in fact it is still an HTTP request

Even if the dead type is not Httpwebrequest, the identified object is still an instance of Httpwebrequest. The essence of this service is to provide HTTP requests

To be certified

 

If it is FTP: / /… Then it should be FTP webrequest

This method of webclient should only be used to fetch WSDL for processing,

I try to use Httpwebrequest and get method directlyhttp://localhost/ESBService/VitalSign.svc?wsdl The method description XML in a service is returned,

However, I tried to send Httpwebrequest directly according to the request content of the second package, but it didn’t succeed (error 500, internal server error), maybe my parameter processing was wrong.

The webclient mode and the direct Httpwebrequest mode should be interoperable and convertible,

However, webclient uses Httpwebrequest to encapsulate other processing, which reduces the work of programmers to some extent. It is the problem of data structure integration, which is not studied much.

 

Webclient encapsulates part of the content (header, etc.) of Httpwebrequest. It also provides some methods,

Here is an example of the application of asynchronous requests to trigger events after receiving a response. However, this example is quite old. In 2008:

https://docs.microsoft.com/zh-cn/archive/blogs/silverlight_sdk/using-webclient-and-httpwebrequest

 

In. Net, webrequest is different from Httpwebrequest. It feels very similar in terms of name, and the decompilation result is.

Requests (with different protocols) constructed by the customer service end are sent to the server

WebRequest

FtpWebRequest

FileWebRequest

HttpWebRequest

WebSocket

Abstract base class

Inherited from webrequest

Inherited from webrequest

Inherited from webrequest

Abstract base class

Paired with webresponse

FTP: / /

It starts with file: /, which is usually to open the local file,

In the form of:

file:///C:/Users/dududu/0209.pdf

file://dududu/Share2021/

Starting with http: / /

Start with WS: / /

wss:// 

 

 

 

Websocket is mainly used in the page by JavaScript. It doesn’t need to wait for a whole page file to return like HTTP request. It only takes business data.

Click here for reference

 

Put some addresses to the observation, perception, request and acceptance of the mode of operation, each has its own personality, different ways to the same end:

http://192.168.8.100:9000/empId=&jobId=

The get method is equivalent to a service address with such a format, which can return a hypertext content (web page) or some data in a certain format.

(I’m curious about how the server responds to the network. It’s always pale to know the configuration.)

http://172.18.99.100:8080/yyzx/index.action?userName=&passWord=

This is equivalent in some web addresses. Where (service configuration, architecture configuration, etc.) should handle this logic

http://192.168.29.100:8081/emr/index.php/index/emr/getemr?personid=7321446

http://192.168.29.100:8081/emr/index.php/index/emr/getemr/personid/7321446

 

Attached:Click to download the complete code