WebAPI主旨目的解析

 
 对于.NET的分布式应用开垦,能够供我们选用的才具和框架比较多,举例webservice,.net
remoting,MSMQ,WCF等等技巧。对于这几个本事很两人都不会不熟悉,即时未有深刻的询问,可是一定听别人讲过,各样技能都各有优势和适用范围,未有绝对的好坏,唯有相对的适合程度。不过可惜了,前天我们讲课的焦点不是那二种本事,后天重大教授的是ASP.NET
WebAPI。

   对于ASP.NET
WebAPI的优势和特点,在此处就不讲了,要求使用的当然就会选用,也不要求本人浪费篇幅去上课这么些,那篇博文首要批注ASP.NET
WebAPI中的HTTP音信的构造和拍卖音讯的中坚目的。

一.WebAPI的HTTP概述:

 
 有关HTTP协议的相关内容在那里就不做牵线,在笔者后面的博文中早已做过介绍,未来提供一下地址,因为过多的废话正是浪费时间,小编就姑且看那篇博文的读者已经对HTTP协议和WebAPI都有所领会。博文地址:

http://www.cnblogs.com/pengze0902/p/5976388.html

http://www.cnblogs.com/pengze0902/p/6224792.html

http://www.cnblogs.com/pengze0902/p/6230105.html

   一.在.NET四.5事先的本子中,管理HTTP的中坚目的:

     
(一).在客户端:System.Net.HttpWebRequest用于伊始化HTTP请求,管理有关的响应; System.Net.HttpWebResponse管理HTTP响应头和数目读取的探求。

     
(二).在劳务器端:System.Web.HttpContext,System.Web.HttpRequest,System.Web.HttpResponse类用在ASP.NET上下文中,代表单个请求和响应。System.Net.HttpListenerContext类,提供对HTTP请求和响应对象的走访。

   2.在.NET四.5本子中,管理HTTP的中坚目的:

亚洲必赢bwin696.com,     
(壹).在客户端和劳务器端使用同样的类。(HttpRequestMessage和HttpResponseMessage对象中不分包上下文新闻,所以能够在服务器和客户端共用。)

     
(二).由于在.NET肆.5中引进了TAP(异步职责模型),所以在新的HTTP模型中,管理HTTP请求的措施能够应用async和awit实现异步编制程序。(能够轻巧高效的贯彻异步编程)

   
大家对于新旧的HTTP编制程序模型时,会很轻巧的意识在新本子的HTTP模型中,无论是编制程序的难度和代码编写的精简度,已经施行的作用都是相当高的。在对于Web项目标付出中,大家对HTTP知识的垂询是至关重要的,对于ASP.NET的HTTP管理的法则在此处就不做具体的牵线,网络也有相比较多的小说可供阅读和精晓。

   
对于ASP.NET的HTTP管理格局的刺探,是自身在支付微信公众平台时越发学习的,微信公众平台提供了对外访问的接口,大家的主次和服务器对微信服务器的接口进行呼吁访问,微信服务器获取HTTP请求后,再次来到管理结果,本地服务器获取重返结果。那样一个伸手-响应情势,组成一个对话。对于微信公众平台的开销对于广大刚学习.NET的人来讲多少高大(当然那是周旋来说),即时开拓过很频仍这一个类型的次第的人(调用第三方接口的付出)也不确定能够很清晰的敞亮这些里面包车型大巴规律,作者以为对于这么的第二方平台的开支,其主要的主干部分正是对于HTTP协议的拍卖,建立请求、获取响应信息和剖析新闻那3大步骤,再次回到的音信内容相似为json或许xml,获取响应新闻后,首假诺对音信内容的反种类化,获得新闻的实业新闻,进而在程序中特别管理。

   
在WeAPI中国国投息的产生和剖析,以及音信的格式都以能够动态的开创和情商,上边大家更为的打听完成那壹经过的大旨目的。

二.WebAPI的HTTP新闻分析:

     
HTTP协议的劳作方式是在客户端和服务器之间沟通请求和响应音讯,那么这也就可以证实HTTP的基本就是音信,对于“新闻”的打听,大家假设了然新闻分为“信息底部”和“消息内容”,大家接下去的对新HTTP编制程序模型的介绍的关键性正是“音讯底部”和“消息内容”。

     
在命名空间System.Net.Http中,具备八个为主目的:HttpRequestMessage和HttpResponseMessage。四个对象的组织如下图:

亚洲必赢bwin696.com 1

     
以上海重机厂点教学了HttpRequestMessage对象和HttpResponseMessage对象涵盖的首要内容,请求和响应音讯都得以涵盖2个可选的音讯正文,两中国国际信资公司息类型以及音信内容,都能够选拔响应的标头。接下来具体理解部分信息的构造。

    一.HttpRequestMessage目的解析:

         (一).HttpRequestMessage首要质量和方法概述:

名称 说明
Version 获取或设置 HTTP 消息版本
Content 获取或设置 HTTP 消息的内容
Method 获取或设置 HTTP 请求信息使用的 HTTP 方法
RequestUri 获取或设置 HTTP 请求的 Uri
Headers 获取 HTTP 请求标头的集合
Properties 获取 HTTP 请求的属性集
ToString 返回表示当前对象的字符串

        该目的主要用来表示 HTTP
请求新闻。对于该对象的这几个属性和措施,超过八分之四应有都不会面生,因为二个HTTP新闻中首要含有底部、音讯内容等等,在此地根本介绍1个属性Properties,该属性并不属于别的正式的HTTP音信,当音讯传输时,不会保留该属性。

         (二).Properties属性解析:

[__DynamicallyInvokable]
public IDictionary<string, object> Properties
{
    [__DynamicallyInvokable]
    get
    {
        if (this.properties == null)
        {
            this.properties = new Dictionary<string, object>();
        }
        return this.properties;
    }
}

   
有上述的代码能够很领会的看来该属性唯有一个只读属性,并回到贰个IDictionary<string,
object>。当音信在服务器也许客户端本地开始展览管理时,该属性用于保存附加的新闻音信。该属性只是三个通用的容器,保存本地消息属性。(与接受消息的连年相关的客户端认证;将音信与布局路由举办相称,得到的路由数据)

   二.HttpResponseMessage对象解析:

        (1).HttpRequestMessage首要品质和方法概述:

名称 说明
EnsureSuccessStatusCode 如果 HTTP 响应的 IsSuccessStatusCode 属性为  false, 将引发异常
StatusCode 获取或设置 HTTP 响应的状态代码
ReasonPhrase 获取或设置服务器与状态代码通常一起发送的原因短语
RequestMessage 获取或设置导致此响应消息的请求消息
IsSuccessStatusCode 获取一个值,该值指示 HTTP 响应是否成功

     
对于该目标的某个性格未有列举,因为在HttpRequestMessage对象已经介绍,如:Version、Content、Headers等,该对象主要用于表示
HTTP 响应消息。在此处关键介绍StatusCode属性。

       (2).StatusCode属性:

[__DynamicallyInvokable]
public HttpStatusCode StatusCode
{
    [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    get
    {
        return this.statusCode;
    }
    [__DynamicallyInvokable]
    set
    {
        if ((value < ((HttpStatusCode) 0)) || (value > ((HttpStatusCode) 0x3e7)))
        {
            throw new ArgumentOutOfRangeException("value");
        }
        this.CheckDisposed();
        this.statusCode = value;
    }
}

   
 StatusCode属性为枚举属性,该属性可读可写,对于状态码那个概念,很三人都以相比较通晓的,在HTTP协议中,状态码首即使表示在消息的央求在服务器中拍卖的结果,状态有二XX,三XX,4XX,伍XX等等,具体表示的含义就不再描述。

     3.HTTP模子新闻标头解析:

         
在HTTP中,请求和响应音信,以及消息内容我,都能够行使称为标头的附加字段,包涵越多的新闻。

       (一).标头分类:

标头名称 描述 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]
public void Add(string name, string value)
{
    HeaderStoreItemInfo info;
    bool flag;
    this.CheckHeaderName(name);
    this.PrepareHeaderInfoForAdd(name, out info, out flag);
    this.ParseAndAddValue(name, info, value);
    if (flag && (info.ParsedValue != null))
    {
        this.AddHeaderToStore(name, info);
    }
}

     
 Add()方法具备多少个重载版本,该方式能够向容器增加标头,要是要加上的标头有标准名,在增加前面标头值会进展表达。Add方法还会注解标头是或不是能够有五个值。

   4.HTTP音讯内容分析:

     
在.NET四.伍本子的HTTP模型中,HTTP新闻的正文由抽象基类HttpContent表示,HttpResponseMessage和HttpRequestMessage对象都饱含二个HttpContent类型的Content属性。

     (一).HttpContent主要质量和章程:

名称 描述
ReadAsByteArrayAsync 以异步操作将 HTTP 内容写入字节数组。
SerializeToStreamAsync 以异步操作将 HTTP 内容序列化到流。
CopyToAsync 以异步操作将 HTTP 内容写入流。
LoadIntoBufferAsync 以异步操作将 HTTP 内容序列化到内存缓冲区。
CreateContentReadStreamAsync 以异步操作将 HTTP 内容写入内存流。
TryComputeLength 确定 HTTP 内容是否具备有效的字节长度。
Headers 根据 RFC 2616 中的定义,获取内容标头。

     (贰).CopyToAsync()方法分析:

[__DynamicallyInvokable]
public Task CopyToAsync(Stream stream, TransportContext context)
{
    Action<Task> continuation = null;
    this.CheckDisposed();
    if (stream == null)
    {
        throw new ArgumentNullException("stream");
    }
    TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
    try
    {
        Task task = null;
        if (this.IsBuffered)
        {
            task = Task.Factory.FromAsync<byte[], int, int>(new Func<byte[], int, int, 
            AsyncCallback, object, IAsyncResult>(stream.BeginWrite), new Action<IAsyncResult>(stream.EndWrite), 
       this.bufferedContent.GetBuffer(), 0, (int) this.bufferedContent.Length, null);
        }
        else
        {
            task = this.SerializeToStreamAsync(stream, context);
            this.CheckTaskNotNull(task);
        }
        if (continuation == null)
        {
            continuation = delegate (Task copyTask) {
                if (copyTask.IsFaulted)
                {
                    tcs.TrySetException(GetStreamCopyException(copyTask.Exception.GetBaseException()));
                }
                else if (copyTask.IsCanceled)
                {
                    tcs.TrySetCanceled();
                }
                else
                {
                    tcs.TrySetResult(null);
                }
            };
        }
        task.ContinueWithStandard(continuation);
    }
    catch (IOException exception)
    {
        tcs.TrySetException(GetStreamCopyException(exception));
    }
    catch (ObjectDisposedException exception2)
    {
        tcs.TrySetException(GetStreamCopyException(exception2));
    }
    return tcs.Task;
}

   
在利用新闻内容时,需求运用HtppContent的方法或然扩大方法。在HttpContent中运用CopyToAsync()方法以推送形式访问原本的新闻内容,由艺术代码能够看到,该方式接受五个参数,二个是流对象,叁个是关于传输的新闻(举例,通道绑定),此参数可以为null。该办法能够把消息内容写入到那些流中。

    在该办法的贯彻代码中
创设了多个TaskCompletionSource<object>的泛型对象,该对象表示未绑定到委托的 Task<TResult> 的创制者方,并经过 Task 属性提供对使用者方的走访。SerializeToStreamAsync方法将盛传的流对象系列化,该方式为异步方法。

   
我们供给小心的几点,重要为委托的成立和选用,在C#中,尽量采纳有.NET提供的委托类,不要本人去创建。还有有些就是在先后中对越发的管理格局,万分的破获具备档案的次序性,并且调用了自定义的二个那一个管理方式TrySetException。

    (二).ReadAsStreamAsync()方法分析:

     
在得到原始音信内容时,除了调用上边介绍的主意外,还足以调用ReadAsStreamAsync()方法以拉取的章程访问原本的音讯内容。

     
在HttpContent中富含有其它七个像样的秘诀,ReadAsStringAsync()和ReadAsByteArrayAsync()异步的提供音信内容的缓冲别本,ReadAsByteArrayAsync()重临原始的字节内容,ReadAsStringAsync()将内容解码为字符串再次来到。

叁.DotNet中新旧HTTP模型分析:

   一..NET肆.5事先版本创立HTTP POST请求实例:

        public static string HttpPost(string postUrl, string postData)
        {
            if (string.IsNullOrEmpty(postUrl))
                throw new ArgumentNullException(postUrl);
            if (string.IsNullOrEmpty(postData))
                throw new ArgumentNullException(postData);
            var request = WebRequest.Create(postUrl) as HttpWebRequest;
            if (request == null)
                throw new ArgumentNullException("postUrl");
            try
            {
                var cookieContainer = new CookieContainer();
                request.CookieContainer = cookieContainer;
                request.AllowAutoRedirect = true;
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                var data = Encoding.UTF8.GetBytes(postData);
                request.ContentLength = data.Length;
                var outstream = request.GetRequestStream();
                outstream.Write(data, 0, data.Length);
                outstream.Close();
                //发送请求并获取相应回应数据,获取对应HTTP请求的响应
                var response = request.GetResponse() as HttpWebResponse;
                if (response != null)
                {
                    var instream = response.GetResponseStream();
                    var content = string.Empty;
                    if (instream == null)
                    {
                        return content;
                    }
                    using (var sr = new StreamReader(instream, Encoding.UTF8))
                    {
                        content = sr.ReadToEnd();
                    }
                    return content;
                }
            }
            catch (ArgumentException arex)
            {
                throw arex;
            }
            catch (IOException ioex)
            {
                throw ioex;
            }
            return null;
        }

   二..NET4.伍版本创立HTTP POST请求实例:

async static void getResponse(string url)
        {
            using (HttpClient client = new HttpClient())
            {
                using (HttpResponseMessage response = await client.GetAsync(url))
                {
                    using (HttpContent content = response.Content)
                    {
                        string myContent = await content.ReadAsStringAsync();
                    }
                }
            }
        }
        async static void postResponse(string url)
        {
            while (true)
            {
                IEnumerable<KeyValuePair<string, string>> queries = new List<KeyValuePair<string, string>>()
            {
                new KeyValuePair<string, string> ("test","test")
            };
                HttpContent q = new FormUrlEncodedContent(queries);
                using (HttpClient client = new HttpClient())
                {
                    using (HttpResponseMessage response = await client.PostAsync(url, q))
                    {
                        using (HttpContent content = response.Content)
                        {
                            string myContent = await content.ReadAsStringAsync();

                            Console.WriteLine(myContent);
                        }
                    }
                }
            }
        }

四.总结:

 
 以上主要批注了.NET四.五事先和事后版本对HTTP编制程序格局的局地剧情, 两者的第三差距在于.NET四.5版本此前的HTTP编制程序模型会区分客户端和服务器,两者采纳的对象存在不一样,完成的法则上尽管存在一定的相似性,但是采用的类却区别。.NET四.5以往的版本中,对象的应用未有客户端和服务器之分,两者能够共用。

相关文章