Asp.NetWebAPI核心对象解析
对于.NET的分布式应用开发,可以供我们选择的技术和框架比较多,例如webservice,.netremoting,MSMQ,WCF等等技术。对于这些技术很多人都不会陌生,即时没有深入的了解,但是肯定听说过,每种技术都各有优势和适用范围,没有绝对的好坏,只有相对的合适程度。不过可惜了,今天我们讲解的主题不是这几种技术,今天主要讲解的是ASP.NETWebAPI。
对于ASP.NETWebAPI的优势和特点,在这里就不讲了,需要用到的自然就会选择,也不需要我浪费篇幅去讲解这些,这篇博文主要讲解ASP.NETWebAPI中的HTTP消息的结构和处理消息的核心对象。
一.WebAPI的HTTP概述:
有关HTTP协议的相关内容在这里就不做介绍,在笔者前面的博文中已经做过介绍,现在提供一下地址,因为过多的赘述就是浪费时间,我就姑且看这篇博文的读者已经对HTTP协议和WebAPI都有所了解。
1.在.NET4.5之前的版本中,处理HTTP的核心对象:
(1).在客户端:System.Net.HttpWebRequest用于初始化HTTP请求,处理相关的响应;System.Net.HttpWebResponse处理HTTP响应头和数据读取的检索。
(2).在服务器端:System.Web.HttpContext,System.Web.HttpRequest,System.Web.HttpResponse类用在ASP.NET上下文中,代表单个请求和响应。System.Net.HttpListenerContext类,提供对HTTP请求和响应对象的访问。
2.在.NET4.5版本中,处理HTTP的核心对象:
(1).在客户端和服务器端使用同样的类。(HttpRequestMessage和HttpResponseMessage对象中不包含上下文消息,所以可以在服务器和客户端共用。)
(2).由于在.NET4.5中引入了TAP(异步任务模型),所以在新的HTTP模型中,处理HTTP请求的方法可以使用async和awit实现异步编程。(可以简单高效的实现异步编程)
我们对于新旧的HTTP编程模型时,会很容易的发现在新版本的HTTP模型中,无论是编程的难度和代码编写的精简度,已经执行的效率都是很高的。在对于Web项目的开发中,我们对HTTP知识的了解是必要的,对于ASP.NET的HTTP处理的原理在这里就不做具体的介绍,网上也有比较多的文章可供阅读和了解。
对于ASP.NET的HTTP处理方式的了解,是我在开发微信公众平台时进一步学习的,微信公众平台提供了对外访问的接口,我们的程序和服务器对微信服务器的接口进行请求访问,微信服务器获取HTTP请求后,返回处理结果,本地服务器获取返回结果。这样一个请求-响应模式,组成一个会话。对于微信公众平台的开发对于很多刚学习.NET的人来说有些高大(当然这是相对而言),即时开发过很多次这个类别的程序的人(调用第三方接口的开发)也不一定可以很清晰的知道这个其中的原理,笔者觉得对于这样的第三方平台的开发,其主要的核心部分就是对于HTTP协议的处理,建立请求、获取响应消息和解析消息这三大步骤,返回的消息内容一般为json或者xml,获取响应消息后,主要是对消息内容的反序列化,获得消息的实体信息,进而在程序中进一步处理。
在WeAPI中消息的产生和解析,以及消息的格式都是可以动态的创建和协商,下面我们进一步的了解实现这一过程的核心对象。
二.WebAPI的HTTP消息解析:
HTTP协议的工作方式是在客户端和服务器之间交换请求和响应消息,那么这也就可以说明HTTP的核心就是消息,对于“消息”的了解,我们只要知道消息分为“消息头部”和“消息内容”,我们接下来的对新HTTP编程模型的介绍的主体就是“消息头部”和“消息内容”。
在命名空间System.Net.Http中,具有两个核心对象:HttpRequestMessage和HttpResponseMessage。两个对象的结构如下图:
以上主要讲解了HttpRequestMessage对象和HttpResponseMessage对象包含的主要内容,请求和响应消息都可以包含一个可选的消息正文,两中消息类型以及消息内容,都可以使用响应的标头。接下来具体了解一些消息的结构。
1.HttpRequestMessage对象解析:
(1).HttpRequestMessage主要属性和方法概述:
名称 说明
Version 获取或设置HTTP消息版本
Content 获取或设置HTTP消息的内容
Method 获取或设置HTTP请求信息使用的HTTP方法
RequestUri 获取或设置HTTP请求的Uri
Headers 获取HTTP请求标头的集合
Properties 获取HTTP请求的属性集
ToString 返回表示当前对象的字符串
该对象主要用于表示HTTP请求消息。对于该对象的这些属性和方法,大部分应该都不会陌生,因为一个HTTP消息中主要包含头部、消息内容等等,在这里主要介绍一个属性Properties,该属性并不属于任何标准的HTTP消息,当消息传输时,不会保留该属性。
(2).Properties属性解析:
复制代码
[__DynamicallyInvokable]
publicIDictionaryProperties
{
[__DynamicallyInvokable]
get
{
if(this.properties==null)
{
this.properties=newDictionary();
}
returnthis.properties;
}
}
复制代码
有以上的代码可以很明显的看出该属性只有一个只读属性,并返回一个IDictionary。当消息在服务器或者客户端本地进行处理时,该属性用于保存附加的消息信息。该属性只是一个通用的容器,保存本地消息属性。(与接受消息的连接相关的客户端认证;将消息与配置路由进行匹配,得到的路由数据)
2.HttpResponseMessage对象解析:
(1).HttpRequestMessage主要属性和方法概述:
名称 说明
EnsureSuccessStatusCode 如果HTTP响应的IsSuccessStatusCode属性为false,将引发异常
StatusCode 获取或设置HTTP响应的状态代码
ReasonPhrase 获取或设置服务器与状态代码通常一起发送的原因短语
RequestMessage 获取或设置导致此响应消息的请求消息
IsSuccessStatusCode 获取一个值,该值指示HTTP响应是否成功
对于该对象的一些属性没有列举,因为在HttpRequestMessage对象已经介绍,如:Version、Content、Headers等,该对象主要用于表示HTTP响应消息。在这里主要介绍StatusCode属性。
(2).StatusCode属性:
复制代码
[__DynamicallyInvokable]
publicHttpStatusCodeStatusCode
{
[__DynamicallyInvokable,TargetedPatchingOptOut("PerformancecriticaltoinlinethistypeofmethodacrossNGenimageboundaries")]
get
{
returnthis.statusCode;
}
[__DynamicallyInvokable]
set
{
if((value<((HttpStatusCode)0))||(value>((HttpStatusCode)0x3e7)))
{
thrownewArgumentOutOfRangeException("value");
}
this.CheckDisposed();
this.statusCode=value;
}
}
复制代码
StatusCode属性为枚举属性,该属性可读可写,对于状态码这个概念,很多人都是比较了解的,在HTTP协议中,状态码主要是表示在消息的请求在服务器中处理的结果,状态有2XX,3XX,4XX,5XX等等,具体表示的意义就不再描述。
3.HTTP模型消息标头解析:
在HTTP中,请求和响应消息,以及消息内容自身,都可以使用称为标头的额外字段,包含更多的信息。
(1).标头分类:
标头名称 描述 HTTP模型标头容器类
User-Agent 为请求提供扩展信息,描述产生这个请求的应用程序 HttpRequestHeaders
Server 为响应提供关于源服务器软件的扩展信息 HttpResponseHeaders
Content-Type 定义请求或响应有效载荷正文中,资源表示使用的媒体类型 HttpContentHeaders
(2).HttpHeaders抽象类分析:
名称 描述
Add 添加指定的标头及其值到HttpHeaders集合中。
TryAddWithoutValidation 返回一个值,该值指示指定标头及其值是否已添加到HttpHeaders集合,而未验证所提供的信息。
Clear 从HttpHeaders集合中移除所有标头。
Remove 从HttpHeaders集合中移除指定的标头。
GetValues 返回存储在HttpHeaders集合中所有指定标头的标头值。
Contains 如果指定标头存在于HttpHeaders集合则返回。
ToString 返回表示当前HttpHeaders对象的字符串。
HttpHeaders是一个抽象类,HttpRequestHeaders、HttpResponseHeaders、HttpContentHeaders三个类继承了该类。接下来我们来了解一下Add()方法:
复制代码
[__DynamicallyInvokable]
publicvoidAdd(stringname,stringvalue)
{
HeaderStoreItemInfoinfo;
boolflag;
this.CheckHeaderName(name);
this.PrepareHeaderInfoForAdd(name,outinfo,outflag);
this.ParseAndAddValue(name,info,value);
if(flag&&(info.ParsedValue!=null))
{
this.AddHeaderToStore(name,info);
}
}
复制代码
Add()方法具有两个重载版本,该方法可以向容器添加标头,如果要添加的标头有标准名,在添加之前标头值会进行验证。Add方法还会验证标头是否可以有多个值。
4.HTTP消息内容解析:
在.NET4.5版本的HTTP模型中,HTTP消息的正文由抽象基类HttpContent表示,HttpResponseMessage和HttpRequestMessage对象都包含一个HttpContent类型的Content属性。
(1).HttpContent主要属性和方法:
名称 描述
ReadAsByteArrayAsync 以异步操作将HTTP内容写入字节数组。
SerializeToStreamAsync 以异步操作将HTTP内容序列化到流。
CopyToAsync 以异步操作将HTTP内容写入流。
LoadIntoBufferAsync 以异步操作将HTTP内容序列化到内存缓冲区。
CreateContentReadStreamAsync 以异步操作将HTTP内容写入内存流。
TryComputeLength 确定HTTP内容是否具备有效的字节长度。
Headers 根据RFC2616中的定义,获取内容标头。
(2).CopyToAsync()方法解析:
复制代码
[__DynamicallyInvokable]
publicTaskCopyToAsync(Streamstream,TransportContextcontext)
{
Actioncontinuation=null;
this.CheckDisposed();
if(stream==null)
{
thrownewArgumentNullException("stream");
}
TaskCompletionSource |
|