• HttpWebRequest详解


    Determining Whether the Device Is Connected

     

    Most network applications need to know whether the device is currently connected to the network. A well-designed mobile application allows the user to make use of it even if the device isn’t connected. For example, if the device has lost wireless connectivity, it should be able to operate using data cached on the device, and then possibly re-sync with a server when network connectivity is regained.

    There is no class in the .NET Compact Framework that raises events to inform an application when connection to the network is lost and regained. Instead, you must code with this eventuality in mind and make sure your application is tolerant of network outages. You might need to write code that polls for a network resource to determine when the device has network connectivity.
    For example, if your application uses XML Web services, you might need to connect to the service to upload data changes and download data to the device when a network connection is available. In your application, you should write a method that uses the WebResponse class to send an HTTP GET request to a valid URL on the server where the XML Web service is located. If the HttpWebResponse.StatusCode property in the response equals HttpStatusCode.OK, connectivity to the server is confirmed. You should call this method from a TimerEvent of a System.Threading.Timer instance to poll the server at intervals; when the method succeeds, the application knows that it can make a successful HTTP connection to the server, so the interaction with the XML Web service or access to other network resources can proceed.

    Understanding WebRequest and WebResponse Basics

    The most important classes in the System.Netnamespace are the WebRequest and WebResponse classes, which are abstract classes.
    using System.Net;
    using System.IO;

        WebRequest req = WebRequest.Create(uri);
        WebResponse res = req.GetResponse();    // GetResponse blocks until the response arrives
        Stream ReceiveStream = res.GetResponseStream();    // Read the stream into a string
        StreamReader sr = new StreamReader( ReceiveStream );
        string resultstring = sr.ReadToEnd();

    Fetching a Resource Using HTTP

    If the scheme of the URI is http:// or https://, the Create method returns an instance of the HttpWebRequest class. The GetResponse method of this instance makes a request to the resource and returns an HttpWebResponse instance that contains the response.


    using System;
    using System.IO;
    using System.Net;

    namespace NETCFDevelopersReference
    {
        
    class HttpGetSample
        
    {
            
    /// <summary>
            
    /// The main entry point for the application.
            
    /// </summary>

            static void Main(string[] args)
            
    {
                HttpGetSample thisclass 
    = new HttpGetSample();
                thisclass.getPage(
    "target URL here"); // <-- EDIT THIS!
            }


            
    public void getPage(String url) 
            
    {
                WebResponse result 
    = null;

                
    try 
                
    {
                    WebRequest req 
    = WebRequest.Create(url);
                    result 
    = req.GetResponse();
                    Stream ReceiveStream 
    = result.GetResponseStream();

                    
    //read the stream into a string
                    StreamReader sr = new StreamReader( ReceiveStream );
                    
    string resultstring = sr.ReadToEnd();

                    Console.WriteLine(
    "\r\nResponse stream received");
                    Console.WriteLine(resultstring);
                }
     
                
    catch(Exception exp) 
                
    {
                    Console.Write(
    "\r\nRequest failed. Reason:");
                    Console.WriteLine(exp.Message);
                }
     
                
    finally 
                
    {
                    
    if ( result != null ) 
                    
    {
                        result.Close();
                    }

                }


                Console.WriteLine(
    "\r\nPress Enter to exit.");
                Console.ReadLine();
            }
        
        }

    }


    The Finally block ensures that the WebResponse object is closed, regardless of the success or failure of the program. This is important to ensure that network resources are not wasted.

    Handling Errors

    You get an exception of type UriFormatException when the URI cannot be parsed or an exception of type WebException for other errors. The Status property of WebException returns a value from the WebExceptionStatus enumeration. If Status is WebExceptionStatus.ProtocolError, the exception is a result of an HTTP protocol error. You can then access the WebException.Response property, which returns an HttpWebResponse object containing the response from the server. Use the HttpWebResponse.StatusCode property to find out the HTTP status code the server sent back, and use HttpWebResponse.StatusDescription to obtain the description string that corresponds to that status code.

    Working with HTTP Headers


    The HttpWebRequest class allows you to control the HTTP headers sent with your request, which you do by setting properties or by executing methods of the class.

    HTTP Headers Sent

    HTTP Header

    Set By

    Accept

    HttpWebRequest.Accept property

    Connection

    HttpWebRequest.Connection and HttpWebRequest.KeepAlive properties

    Content-Length

    HttpWebRequest.ContentLength property

    Expect

    HttpWebRequest.Expect property

    Date

    Set to the current system date

    Host

    Not set

    If-Modified-Since

    HttpWebRequest.IfModifiedSince property

    Range

    HttpWebRequest.AddRange method

    Referer

    HttpWebRequest.Referer property

    Transfer-Encoding

    HttpWebRequest.TransferEncoding property (the HttpWeb­Request.SendChunked property must be true)

    User-Agent

    HttpWebRequest.UserAgent property

    The HttpWebResponse instance exposes HTTP headers as properties in a similar way.
     

    HTTP Headers Received

    HTTP Header

    Read By

    Content-Encoding

    HttpWebResponse.ContentEncoding property

    Content-Length

    HttpWebResponse.ContentLength property

    Content-Type

    HttpWebResponse.ContentType property

    Length

    HttpWebResponse.Length property

    Server

    HttpWebResponse.Server property


    Both classes also have a Headers property that exposes HTTP headers as a System.Net.WebHeaderCollection instance. For example, instead of using the UserAgent property, you can add the User-Agent header using the following code:

    HttpWebRequest req = (HttpWebRequest) WebRequest.Create(uri);
    req.Headers.Add(
    "User-Agent""dotNETCF Test Program");

    HttpWebResponse res 
    = (HttpWebResponse) req.GetResponse();
    String server 
    = res.Headers["Server"];

    Network Transfer Encoding

    All data transferred over the network is encoded. The Windows CE operating system uses Unicode to represent characters, but this requires at least 2 bytes to represent any character, which is not as efficient as the U.S. ASCII character set, which requires only one byte per character. But ASCII represents only commonly used characters in Western alphabets, so it is unusable in languages requiring other characters, such as European languages, Chinese, Japanese, or Arabic.

    The compromise solution is to use character encodings. The most common of these is UTF-8, which is a variable-length multibyte encoding requiring a single byte for 7-bit characters that are in the U.S. ASCII character set and 2 bytes for characters outside it. This results in efficient encodings for Western alphabets and the flexibility to handle non-Latin characters.

    The default encoding assumed by the HttpWebRequest and HttpWebResponse classes is UTF-8

    You can determine the character set encoding of a response by getting the HttpWebResponse.CharacterSet property. However, beware, there is a trick to this! You must set the MediaType property on the request; otherwise, the CharacterSet property on the HttpWebResponse will be blank. Even then, CharacterSet will only return the character set encoding used if the first part of the Content-Type header returned with the response (which is the media type) matches the value you set in the MediaType property of the request.

    For example, if you set HttpWebRequest.MediaType to “text/html” before calling HttpWeb­Request.GetResponse, and the Content-Type header returned with the response is “text/html; charset=utf-8”, the HttpWebResponse.CharacterSet property will contain the name of the character set encoding (“utf-8”) because the “text/html” media type sent in the first part of the Content-Type header matches the value set in HttpWebRequest.MediaType. If the media types differ, HttpWeb­Response.CharacterSet is a null string.

     


     HttpWebRequest req = (HttpWebRequest) WebRequest.Create(url);
        
    // You MUST set the MediaType property on the request, otherwise
        
    // the CharacterSet property on the HttpWebResponse object will be
        
    // blank.
        req.MediaType = "text/html";

        HttpWebResponse result 
    = (HttpWebResponse) req.GetResponse();

        
    // Note that the HttpWebResponse.ContentType property always
        
    // returns the Content-Type header, which will be something like
        
    // "text/html; charset=utf-8"
        string contenttype = result.ContentType;

        
    // Character set encoding may be something like ISO-10646-UCS-2, 
        
    // or UTF-8, us-ascii etc
        string charsetencoding = result.CharacterSet

        
    //read the stream using the decoder
        Stream ReceiveStream = result.GetResponseStream();
        Encoding encode 
    = System.Text.Encoding.GetEncoding(charsetencoding);
        StreamReader sr 
    = new StreamReader( ReceiveStream, encode );

    Using HTTP GET Query String

    In the full .NET Framework, the System.Web.HttpUtility class provides methods to encode and decode URL-encoded data, but this class is not supported in the .NET Compact Framework. You must write your own code to handle URL encoding, such as the example code shown here:


    using System;
    using System.IO;

    namespace NETCFDevelopersReference
    {
        
    /// <summary>
        
    /// Replacement for HttpUtility.UrlEncode
        
    /// </summary>
        public class HttpUtility
        {
            
    public static string UrlEncode(string instring)
            {
                StringReader strRdr 
    = new StringReader(instring);
                StringWriter strWtr 
    = new StringWriter();
                
    int charValue = strRdr.Read();
                
    while (charValue != -1)
                {
                    
    if (((charValue >= 48&& (charValue <= 57)) // 0-9
                        ││((charValue >= 65&& (charValue <= 90)) // A-Z
                        ││((charValue >= 97&& (charValue <= 122))) // a-z
                        strWtr.Write((char) charValue);
                    
    else if (charValue == 32)    // Space
                        strWtr.Write('+');
                    
    else 
                        strWtr.Write(
    "%{0:x2}", charValue);

                    charValue 
    = strRdr.Read();
                }

                
    return strWtr.ToString();
            }
        }
    }

    Using HTTP POST

    To use POST, just set the HttpWebRequest.Method property to “POST” and then proceed as for GET. A typical HTML page shown in a Web browser posts data as key=value pairs, with the data URL-encoded, so your application must format the data in that way if that is what the Web server application expects. If you are simply posting application content or XML, just post it as is.


        public void doPost(String url, String payload) 
        {
            WebRequest req 
    = WebRequest.Create(url);
            req.Method 
    = "POST";
            req.ContentType 
    = "text/plain; charset=utf-8";

            
    // Encode the data
            byte[] encodedBytes = Encoding.UTF8.GetBytes(payload);
            req.ContentLength 
    = encodedBytes.Length;

            
    // Write encoded data into request stream
            Stream requestStream = req.GetRequestStream();
            requestStream.Write(encodedBytes, 
    0, encodedBytes.Length);
            requestStream.Close();

            WebResponse result 
    = req.GetResponse();
            
        }

    Alternatives to Cookies for Session State Support

    The .NET Compact Framework implementation of the HttpWebResponse class does not support the Cookies property found in the full .NET Framework implementation. 

    If you are using an ASP.NET application on the server, you can utilize the ASP.NET support for cookieless clients to track your smart device applications session. You enable this by setting cookieless to “true” in the sessionState configuration in the ASP.NET application’s Web.Config 

    ASP.NET uses a munged URL to track sessions for cookieless clients, meaning it embeds a session ID into the response URI. For example, if your application makes a request to http://myserver/myserverapp.aspx, the response URI that returns to the client is actually something like http://myserver/(1en4l345qq203lr2f0h4xt45)/myserverapp.aspx. To the client, it looks like a server-side redirect. In the client application, this response URI is in the HttpWebResponse.ResponseUri property, so the client application need only use this URI for subsequent requests for the server application to be able to identify those requests as coming from that particular client.

    Authenticating Requests with the NetworkCredential Class

     WebRequest req = WebRequest.Create(url);
       NetworkCredential creds 
    = 
           
    new NetworkCredential("andy""pA55w0rd""");
       req.Credentials 
    = creds;
       WebResponse result 
    = req.GetResponse();

    Making Network Requests via a Proxy Server

       //  Pass Proxy string and bypass local machine
       WebProxy myProxy = new WebProxy(
         
    "http://myproxyserver.mine.com:8080"true);
       
       
    // If  this proxy requires authentication
       myProxy.Credentials = 
          
    new NetworkCredential("loginname","password");
       
       Request.Proxy 
    = myProxy;

    Asynchronous Web Requests


    using System;
    using System.IO;
    using System.Threading;

    namespace NETCFDevelopersReference
    {
        
    class HttpGetAsyncSample 
        
    {
            
    public static void Main(string[] args) 
            
    {
                HttpGetAsyncSample thisclass 
    = new HttpGetAsyncSample();
                thisclass.Run();
            }


            
    private bool isComplete;

            
    public void Run()
            
    {
                Console.WriteLine();
                Console.WriteLine(
    "Test Program makes HTTP AsyncGet"
                    
    + " to http://www.gotdotnet.com/team/netcf");
                Console.WriteLine(
    "Press Enter to continue");
                Console.ReadLine();

                GetHttpAsync callit 
    = new GetHttpAsync();
                
    // Wire up to handle the complete event
                callit.GetComplete += new 
                    GetHttpAsync.GetCompleteHandler(
    this.GetCompleteHandler);
                
    // Set the flag we will check for completion
                isComplete = false;

                Console.WriteLine(
    "Making async call");
                callit.getPage(
    "http://www.gotdotnet.com/team/netcf");

                Console.WriteLine(
    "Main thread writes these dots, "
                    
    + "while async fetch proceeds");
                Console.WriteLine(
    "in secondary thread");
                
    int count = 0;
                
    while (!isComplete)
                
    {
                    Console.Write(
    ".");
                    
    if (++count == 80) Console.WriteLine();
                    Thread.Sleep(
    500); // Sleep for half a second
                }

                Console.WriteLine(
    "\r\nResponse Received");
                Console.WriteLine(
    "Press Enter to exit");
                Console.ReadLine();

                
    return;
            }


            
    protected void GetCompleteHandler()
            
    {
                
    // Event handler for get complete
                isComplete = true;
            }

        }

    }


     


    using System;
    using System.Net;
    using System.IO;
    using System.Text;

    namespace NETCFDevelopersReference
    {
        
    // The RequestState class is used to pass data
        
    // across async calls
        public class RequestState
        
    {
            
    public HttpWebRequest Request;

            
    public RequestState()
            
    {
                Request 
    = null;
            }

        }


        
    /// <summary>
        
    /// Class makes asynchronous HTTP Get to remote URL
        
    /// </summary>

        public class GetHttpAsync
        
    {
            
    public delegate void GetCompleteHandler();
            
    public event GetCompleteHandler GetComplete;

            
    public void getPage(String url) 
            
    {
                
    try 
                
    {
                    HttpWebRequest req 
    = 
                        (HttpWebRequest) WebRequest.Create(url);
                    
    // Create the state object
                    RequestState rs = new RequestState();

                    
    // Add the request into the state 
                    
    // so it can be passed around
                    rs.Request = req;

                    
    // Issue the async request
                    req.BeginGetResponse(
                        
    new AsyncCallback(this.ResponseCallback), rs);
                }

                
    catch(Exception exp) 
                
    {
                    Console.WriteLine(
    "\r\nRequest failed. Reason:");
                    
    while (exp != null)
                    
    {
                        Console.WriteLine(exp.Message);
                        exp 
    = exp.InnerException;
                    }

                }
     
            }


            
    private void ResponseCallback(IAsyncResult ar)
            
    {
                
    // Get the RequestState object from the async result
                RequestState rs = (RequestState) ar.AsyncState;

                
    // Get the HttpWebRequest from RequestState
                HttpWebRequest req = rs.Request;

                
    // Get the HttpWebResponse object
                HttpWebResponse resp = 
                    (HttpWebResponse) req.EndGetResponse(ar);

                
    // Read data from the response stream
                Stream responseStream = resp.GetResponseStream();
                StreamReader sr 
    = 
                    
    new StreamReader( responseStream, Encoding.UTF8);
                
    string strContent = sr.ReadToEnd();

                
    // Write out the first 512 characters
                Console.WriteLine("Length: {0}", strContent.Length);
                Console.WriteLine(strContent.Substring(
    0
                    strContent.Length 
    < 512 ? strContent.Length : 512));

                
    // Raise the completion event 
                GetComplete();

                
    // Close down the response stream
                responseStream.Close();
            }

        }

    }
  • 相关阅读:
    开发自定义控件步骤
    asp.net后台调用前台js代码
    使用ResolveUrl设置相对路径
    JavaScript获取后台C#变量以及调用后台方法
    使用jquery的验证插件进行客户端验证
    参数化的模糊查询
    使用Microsoft Enterprise Library 5.0记录日志信息
    我的Ajax学习笔记
    我的工作問題集(VS2005)
    存储过程从入门到精通(转载)
  • 原文地址:https://www.cnblogs.com/heiyeqishi/p/2831184.html
Copyright © 2020-2023  润新知