.NET Request、Response开发总结
首先看下Web Request类Web Response类层次结构,如下图1.1 所示,其中有工厂模式的运用。
再看下 MSDN上各个类的说明
WebRequest 类
1 . 发出对统一资源标识符 (URI) 的请求。这是一个 abstract 类。
[SerializableAttribute]
public abstract class WebRequest : MarshalByRefObject, ISerializable
2. WebRequest 是 .NET Framework 的请求/响应模型的 abstract 基类,用于访问 Internet 数据。使用该请求/响应模型的应用程序可以用协议不可知的方式从 Internet 请求数据,在这种方式下,应用程序处理 WebRequest 类的实例,而协议特定的子类则执行请求的具体细节。
请求从应用程序发送到某个特定的 URI,如服务器上的网页。URI 从一个为应用程序注册的 WebRequest 子代列表中确定要创建的适当子类。注册 WebRequest 子代通常是为了处理某个特定的协议(如 HTTP 或 FTP),但是也可以注册它以处理对特定服务器或服务器上的路径的请求。
如果在访问 Internet 资源时发生错误,则 WebRequest 类将引发 WebException。WebException.Status 属性是 WebExceptionStatus 值之一,它指示错误源。当 WebException.Status 为 WebExceptionStatus.ProtocolError 时,Response 属性包含从 Internet 资源接收的 WebResponse。
因为 WebRequest 类是一个 abstract 类,所以 WebRequest 实例在运行时的实际行为由 System.Net.WebRequest.Create 方法所返回的子类确定。有关默认值和异常的更多信息,请参见有关子类的文档,如 HttpWebRequest 和 FileWebRequest。
注意
使用 Create 方法初始化新的 WebRequest 实例。不要使用 WebRequest 构造函数。
下面的示例说明如何创建 WebRequest 实例并返回响应。
using System.IO;
using System.Net;
using System.Text;
namespace Examples.System.Net
{
public class WebRequestGetExample
{
public static void Main ()
{
// Create a request for the URL.
WebRequest request = WebRequest.Create (http://www.cnblogs.com/zycblog/);
// If required by the server, set the credentials.
request.Credentials = CredentialCache.DefaultCredentials;
// Get the response.
HttpWebResponse response = (HttpWebResponse)request.GetResponse ();
// Display the status.
Console.WriteLine (response.StatusDescription);
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream ();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader (dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd ();
// Display the content.
Console.WriteLine (responseFromServer);
// Cleanup the streams and the response.
reader.Close ();
dataStream.Close ();
response.Close ();
}
}
}
HttpWebRequest 类
1. 提供 WebRequest 类的 HTTP 特定的实现。
[SerializableAttribute]
public class HttpWebRequest : WebRequest, ISerializable
2. HttpWebRequest 类对 WebRequest 中定义的属性和方法提供支持,也对使用户能够直接与使用 HTTP 的服务器交互的附加属性和方法提供支持。
不要使用 HttpWebRequest 构造函数。使用 System.Net.WebRequest.Create 方法初始化新的 HttpWebRequest 对象。如果统一资源标识符 (URI) 的方案是 http:// 或 https://,则 Create 返回 HttpWebRequest 对象。
GetResponse 方法向 RequestUri 属性中指定的资源发出同步请��并返回包含该响应的 HttpWebResponse。可以使用 BeginGetResponse 和 EndGetResponse 方法对资源发出异步请求。
当要向资源发送数据时,GetRequestStream 方法返回用于发送数据的 Stream 对象。BeginGetRequestStream 和 EndGetRequestStream 方法提供对发送数据流的异步访问。
对于使用 HttpWebRequest 的客户端验证身份,客户端证书必须安装在当前用户的“我的证书”存储区中。
如果在访问资源时发生错误,则 HttpWebRequest 类将引发 WebException。WebException.Status 属性包含指示错误源的 WebExceptionStatus 值。当 WebException.Status 为 WebExceptionStatus.ProtocolError 时,Response 属性包含从资源接收的 HttpWebResponse。
HttpWebRequest 将发送到 Internet 资源的公共 HTTP 标头值公开为属性,由方法或系统设置;下表包含完整列表。可以将 Headers 属性中的其他标头设置为名称/值对。注意,服务器和缓存在请求期间可能会更改或添加标头。
面的代码示例为 URI http://www.contoso.com/. 创建 HttpWebRequest。
HttpWebResponse 类
1. 提供 WebResponse 类的 HTTP 特定的实现
2. 此类包含对 WebResponse 类中的属性和方法的 HTTP 特定用法的支持。 HttpWebResponse 类用于生成发送 HTTP 请求和接收 HTTP 响应的 HTTP 独立客户端应用程序。
说明
不要混淆 HttpWebResponse 和 HttpResponse 类;后者用于 ASP.NET 应用程序,而且它的方法和属性是通过 ASP.NET 的内部 Response 对象公开的。
决不要直接创建 HttpWebResponse 类的实例。 而应当使用通过调用 HttpWebRequest.GetResponse 所返回的实例。 您必须调用 Stream.Close 方法或 HttpWebResponse.Close 方法来关闭响应并将连接释放出来供重用。 不必同时调用 Stream.Close 和 HttpWebResponse.Close,但这样做不会导致错误。
下面的示例返回 HttpWebRequest 的 HttpWebResponse
(HttpWebRequest)WebRequest.Create(http://www.cnblogs.com/zycblog/);
HttpWebResponse HttpWResp = (HttpWebResponse)HttpWReq.GetResponse();
// Insert code that uses the response object.
HttpWResp.Close();
HttpRequest 类
使 ASP.NET 能够读取客户端在 Web 请求期间发送的 HTTP 值。
public sealed class HttpRequest
HttpRequest 类的方法和属性通过 HttpApplication、HttpContext、Page 和 UserControl 类的 Request 属性公开。
下面的代码示例使用 StreamWriter 类将若干 HttpRequest 类属性值的值写入文件。对于是字符串类型的属性,属性值被写入文件时将被编码为 HTML。表示集合的属性会被依次通过,而这些属性包含的各个键/值对都会被写入该文件。
<%@ Page Language="C#" %>
<%@ import Namespace="System.Threading" %>
<%@ import Namespace="System.IO" %>
<script runat="server">
/* NOTE: To use this sample, create a c:\temp\CS folder,
* add the ASP.NET account (in IIS 5.x <machinename>\ASPNET,
* in IIS 6.x NETWORK SERVICE), and give it write permissions
* to the folder.*/
private const string INFO_DIR = @"c:\temp\CS\RequestDetails";
public static int requestCount;
private void Page_Load(object sender, System.EventArgs e)
{
// Create a variable to use when iterating
// through the UserLanguages property.
int langCount;
int requestNumber = Interlocked.Increment(ref requestCount);
// Create the file to contain information about the request.
string strFilePath = INFO_DIR + requestNumber.ToString() + @".txt";
StreamWriter sw = File.CreateText(strFilePath);
try
{
// Write request information to the file with HTML encoding.
sw.WriteLine(Server.HtmlEncode(DateTime.Now.ToString()));
sw.WriteLine(Server.HtmlEncode(Request.CurrentExecutionFilePath));
sw.WriteLine(Server.HtmlEncode(Request.ApplicationPath));
sw.WriteLine(Server.HtmlEncode(Request.FilePath));
sw.WriteLine(Server.HtmlEncode(Request.Path));
// Iterate through the Form collection and write
// the values to the file with HTML encoding.
// String[] formArray = Request.Form.AllKeys;
foreach (string s in Request.Form)
{
sw.WriteLine("Form: " + Server.HtmlEncode(s));
}
// Write the PathInfo property value
// or a string if it is empty.
if (Request.PathInfo == String.Empty)
{
sw.WriteLine("The PathInfo property contains no information.");
}
else
{
sw.WriteLine(Server.HtmlEncode(Request.PathInfo));
}
// Write request information to the file with HTML encoding.
sw.WriteLine(Server.HtmlEncode(Request.PhysicalApplicationPath));
sw.WriteLine(Server.HtmlEncode(Request.PhysicalPath));
sw.WriteLine(Server.HtmlEncode(Request.RawUrl));
// Write a message to the file dependent upon
// the value of the TotalBytes property.
if (Request.TotalBytes > 1000)
{
sw.WriteLine("The request is 1KB or greater");
}
else
{
sw.WriteLine("The request is less than 1KB");
}
// Write request information to the file with HTML encoding.
sw.WriteLine(Server.HtmlEncode(Request.RequestType));
sw.WriteLine(Server.HtmlEncode(Request.UserHostAddress));
sw.WriteLine(Server.HtmlEncode(Request.UserHostName));
sw.WriteLine(Server.HtmlEncode(Request.HttpMethod));
// Iterate through the UserLanguages collection and
// write its HTML encoded values to the file.
for (langCount=0; langCount < Request.UserLanguages.Length; langCount++)
{
sw.WriteLine(@"User Language " + langCount +": " + Server.HtmlEncode
(Request.UserLanguages[langCount]));
}
}
finally
{
// Close the stream to the file.
sw.Close();
}
lblInfoSent.Text = "Information about this request has been sent to a file.";
}
private void btnSendInfo_Click(object sender, System.EventArgs e)
{
lblInfoSent.Text = "Hello, " + Server.HtmlEncode(txtBoxName.Text) +
". You have created a new request info file.";
}
</script>
<html>
<head>
</head>
<body>
<form runat="server">
<p>
</p>
<p>
Enter your hame here:
<asp:TextBox id="txtBoxName" runat="server"></asp:TextBox>
</p>
<p>
<asp:Button id="btnSendInfo" onclick="btnSendInfo_Click" runat="server"
Text="Click Here"></asp:Button>
</p>
<p>
<asp:Label id="lblInfoSent" runat="server"></asp:Label>
</p>
</form>
</body>
</html>
有关HTTP POST,GET的区别可以参考博客文章
http://www.cnblogs.com/liuhaitao/archive/2008/10/29/1321896.html
下面贴出一段Http post的客户端,服务端代码示例
客户端http Post
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded;charset=GBK";
req.ContentLength = postBytes.Length;
Stream webStream = req.GetRequestStream(); //发送数据
webStream.Write(postBytes, 0, postBytes.Length);
webStream.Close();
//获取返回数据
HttpWebResponse webResponse = (HttpWebResponse)req.GetResponse();
StreamReader reader = new StreamReader(webResponse.GetResponseStream(), Encoding.GetEncoding("GBK"));
sResult = reader.ReadToEnd();
sResult.Trim();
服管器端针对客户的Post 需要返回客户端有用的信息
示例程序如下
protected void Page_Load(object sender, EventArgs e)
{
PageLoad();
}
private void PageLoad()
{
GetParamLog.Info("实时回写开始=======================================");
string ResponseResult = Response();
GetParamLog.Info(ResponseResult);
HttpResponse hr = HttpContext.Current.Response;
hr.Clear();
hr.Write(ResponseResult);
//hr.Flush();
hr.End();
}
private string Response()
{
string ResponseResult="";
try
{
ResponseResult= GetPostInput();
GetParamLog.InfoFormat("请求参数内容:{0}", ResponseResult);
GetParamLog.Info("开始解析请求参数");
string[] ResposeArray = ResponseResult.Split('&');
if (ResposeArray.Length > 0)
{
foreach (string param in ResposeArray)
{
//程序处理逻辑 给ResponseResult赋值,然后返回客户端
}
}
}
catch (Exception ex)
{
GetParamLog.Error(ex.Message);
throw;
}
return ResponseResult;
}
private string GetParam(string[] ParamArray,string ParamName)
{
if (ParamArray.Length <= 0)
{
return "";
}
foreach (string name in ParamArray)
{
if (name.Split('=')[0].ToLower() == ParamName.ToLower())
{
return name.Split('=')[1].ToString();
}
}
return "";
}
private string GetPostInput()
{
try
{
System.IO.Stream s = Request.InputStream;
int count = 0;
byte[] buffer = new byte[1024];
StringBuilder builder = new StringBuilder();
while ((count = s.Read(buffer, 0, 1024)) > 0)
{
builder.Append(Encoding.UTF8.GetString(buffer, 0, count));
}
return builder.ToString();
}
catch (Exception ex)
{
throw ex;
}
}
其中 HttpResponse hr = HttpContext.Current.Response;
hr.Clear();
hr.Write(ResponseResult);
//hr.Flush();
hr.End();
是把客户端需要的结果返回回去