文档章节

HTTP在.NET中的一些应用和解析

彭泽0902
 彭泽0902
发布于 2016/11/24 18:47
字数 1215
阅读 1
收藏 0
点赞 0
评论 0

     谈到HTTP协议(超文本传输协议),HTTP协议是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接的机制,绝大多数的Web开发,都是构建在HTTP协议之上的Web应用。

    HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。HTTP协议的主要特点可概括为:1.支持客户/服务器模式。2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。3.灵活:HTTP允许传输任意类型的数据对象。4.无连接:无连接的含义是限制每次连接只处理一个请求。5.无状态:HTTP协议是无状态协议。

    在.NET框架里面对HTTP协议的处理主要采用WebRequest对象,在我们的.NET项目中如果需要生成HTTP请求或者处理HTTP请求,会运用HttpWebRequest和HttpWebResponse对象。在实际项目的开发中,有一些需求需要同地方平台进行数据交互,例如我们经常使用的微信,支付宝,QQ等等平台,这就需要我们在自己的项目中生成对应的HTTP请求和处理相关HTTP请求信息。

    如何在我们的系统中后台生成对应的HTTP请求,这个事情就需要对HTTP协议做一个简单的了解:

    HTTP请求由三部分组成,分别是:请求行、消息报头、请求正文。HTTP响应也是由三个部分组成,分别是:状态行、消息报头、响应正文。HTTP消息由客户端到服务器的请求和服务器到客户端的响应组成。请求消息和响应消息都是由开始行(对于请求消息,开始行就是请求行,对于响应消息,开始行就是状态行),消息报头(可选),空行(只有CRLF的行),消息正文(可选)组成。

 

   现在提供一个较为通用的处理HTTP请求的代码,此部分主要是生成同步HTTP请求。

   在谈到.NET的同步中,需要介绍一下同步和异步的相关内容:

   同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。  

   异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。 

  

     (以上的图都是从别处截的,感谢提供资料的博主们。)

    现在直接给出相关代码:

   

/// <summary>
         /// 访问次数字典
        /// </summary>
        private readonly ConcurrentDictionary<string, int> _urlTryList = new ConcurrentDictionary<string, int>();
/// <summary>
        /// Post数据
        /// </summary>
        public String PostData { set; private get; }
/// <summary>
        /// 同步请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="tryTimes">错误重试次数</param>
        public string SyncRequest(string url, int tryTimes = 3)
        {
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException(url);
            }
            Trace.TraceInformation(string.Concat("开始同步请求:", url));
            _urlTryList.TryAdd(url, tryTimes);
            //创建并定义HTTP请求相关信息
            var request = WebRequest.Create(url) as HttpWebRequest;
            if (request == null) return string.Empty;
            request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
            request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
            request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate | DecompressionMethods.None;
            request.Credentials = CredentialCache.DefaultNetworkCredentials;
            request.UseDefaultCredentials = false;
            request.KeepAlive = false;
            request.PreAuthenticate = false;
            request.ProtocolVersion = HttpVersion.Version10;
            request.UserAgent =
                "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36";
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
            request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
            request.Timeout = 1000 * 60 * 3;
            request.CookieContainer = CookieContainer;
            request.AllowAutoRedirect = true;
            //判断POST请求是否为空
            if (!string.IsNullOrEmpty(PostData))
            {
                request.ContentType = "application/x-www-form-urlencoded";
                request.Method = "POST";
                using (var postStream = request.GetRequestStream())
                {
                    var byteArray = Encoding.GetBytes(PostData);
                    postStream.Write(byteArray, 0, PostData.Length);
                    postStream.Close();
                }
            }
            else
            {
                request.AllowWriteStreamBuffering = false;
            }
            try
            {
                using (var response = request.GetResponse() as HttpWebResponse)
                {
                    if (response != null)
                    {
                        if (response.StatusCode != HttpStatusCode.OK)
                        {
                            Trace.TraceError(string.Concat("请求地址:", request.RequestUri, " 失败,HttpStatusCode",
                                response.StatusCode));
                            return string.Empty;
                        }
                        using (var streamResponse = response.GetResponseStream())
                        {
                            if (streamResponse != null)
                            {
                                if (!IsText(response.ContentType))
                                {
                                    var contentEncodingStr = response.ContentEncoding;
                                    var contentEncoding = Encoding;
                                    if (!string.IsNullOrEmpty(contentEncodingStr))
                                        contentEncoding = Encoding.GetEncoding(contentEncodingStr);
                                    var streamRead = new StreamReader(streamResponse, contentEncoding);
                                    var str = streamRead.ReadToEnd();
                                    if (CallBackAction != null && !String.IsNullOrEmpty(str))
                                        CallBackAction.BeginInvoke(str, request.RequestUri.ToString(), (s) => { }, null);
                                    return str;
                                }
                                //创建并指定文件夹
                                var fileName = string.Concat(DateTime.Now.ToString("yyyyMMdd"), "/", DateTime.Now.ToString("yyyyMMddHHmmssffff"),
                                    Path.GetExtension(request.RequestUri.AbsoluteUri));
                                var fileDirectory = Path.Combine(FileSavePath, DateTime.Now.ToString("yyyyMMdd"));
                                if (!Directory.Exists(fileDirectory))
                                    Directory.CreateDirectory(fileDirectory);
                                try
                                {
                                    //下载文件
                                    using (var fileStream = new FileStream(Path.Combine(FileSavePath, fileName), FileMode.Create))
                                    {
                                        var buffer = new byte[2048];
                                        int readLength;
                                        do
                                        {
                                            readLength = streamResponse.Read(buffer, 0, buffer.Length);
                                            fileStream.Write(buffer, 0, readLength);
                                        } while (readLength != 0);
                                    }
                                    if (CallBackAction != null && !String.IsNullOrEmpty(fileName))
                                        CallBackAction.BeginInvoke(fileName, request.RequestUri.ToString(), (s) => { }, null);
                                    return fileName;
                                }
                                catch (IOException ex)
                                {
                                    throw new IOException(ex.Message, ex);
                                }
                            }
                        }
                        response.Close();
                    }
                }
            }
            catch (WebException ex)
            {
                Trace.TraceError(string.Concat("请求地址:", request.RequestUri, " 失败信息:", ex.Message));
                var toUrl = request.RequestUri.ToString();
                if (_urlTryList.TryGetValue(toUrl, out tryTimes))
                {
                    _urlTryList.TryUpdate(toUrl, tryTimes, tryTimes - 1);
                    if (tryTimes - 1 <= 0)
                    {
                        _urlTryList.TryRemove(toUrl, out tryTimes);
                        Trace.TraceError(string.Concat("请求地址重试失败:", request.RequestUri));
                        return string.Empty;
                    }
                    SyncRequest(toUrl);
                }
            }
            finally
            {
                request.Abort();
            }
            return string.Empty;
        }

    以上就是对相关概念和代码的解析。有写的不到位的地方,敬请谅解。

© 著作权归作者所有

共有 人打赏支持
彭泽0902
粉丝 0
博文 44
码字总数 57771
作品 0
武汉
高级程序员
Injection Attacks-XML注入

注入攻击 XML注入 虽然JSON的出现实现了服务器与客户端之间的“轻量级”数据交流,但是,作为另一种流行的可行方案,许多web服务API同时还是继续支持XML。另外,除了web服务之外,XML也是许多...

OneAPM蓝海讯通
2016/03/11
23
0
可以在前端实现的几个地理位置小功能

下文转自:http://www.oncoding.cn/2010/geo-location-frontend 在Smashing Magazine上看到这篇Entering The Wonderful World of Geo Location ,介绍了获取并处理用户地理位置的应用和方法,...

晨曦之光
2012/03/09
0
0
将Python嵌入到Qt程序中

(原文链接: http://doc.trolltech.com/qq/qq23-pythonqt.html ) by Florian Link 译: 赖敬文 将脚本语言嵌入C++ 程序已经变得非常普遍。在许多主流的应用程序,如Microsoft Office 与Mac...

openthings
2015/01/20
0
0
使用Android API最佳实践

本文由 伯乐在线 - imesong 翻译自 meetme。欢迎加入Android小组。转载请参见文章末尾处的要求。 写在前面 现在,Android应用程序中集成第三方API已十分流行。应用程序都有自己的网络操作和缓...

mingxun
2014/04/17
0
0
Apache Tika-内容解析提取工具集合(a content analysis toolkit)

简介 Apache Tika toolkit可以自动检测各种文档(如word,ppt,xml,csv,ppt等)的类型并抽取文档的元数据和文本内容。Tika集成了现有的文档解析库,并提供统一的接口,使针对不同类型的文档进行解...

cloud-coder
2014/08/21
0
0
MDIUtilities 0.7 Beta5 发布

MDIUtilities 0.7 Beta5 发布了,该版本的 FileUtilities 类增加了 exist 方法;修复了 getAbsoluteFile 方法在使用 HTTP 协议时总是返回 false 的问题;增加了一些用来处理 URL 的新方法,可...

oschina
2012/11/26
398
0
如何在ArcGIS Online中构建自己的应用程序模板高级篇-利用数据

模板的最大的好处就是在于,只要数据格式一致,可以重复的利用。减少了每一份数据,都需要单独创建一份应用,减少了工作量。 这里我创建了一个很简单的模板,显示了这个item的一些元信息和T...

长平狐
2012/11/28
515
0
Spring Framework 源码阅读+吐槽

吐槽 有人说JAVA企业级应用没啥技术含量,玩不了大数据的技术人员是很杯具的存在。大部分生命的时间是处理复杂的业务,沉迷于一堆框架和API的应用,却没有足够的能力去解决计算机世界里面高深的...

geecoodeer
2014/01/09
0
7
Mainifest的加载和解析

1:它是在系统启动时,被PackagedManageService这样一个系统级的服务加载(所有应用程序的),解析后映射到共享内存中,供使用时查询。 2:当应用程序启动时,launcher会进行一些系统级别的判断...

长平狐
2012/10/09
26
0
Java web部署目录结构和web.xml作用

一、Javaweb 部署目录结构 servlet规范不仅规范了servlet自身处理web请求的通用逻辑过程, 还规范了web服务器管理servlet的通用步骤。 为了使得我们开发的Java web 应用能在多种多样的 Java...

qingfeng哥
2016/09/24
165
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

如何把你的Linux系统变的更加安全

做为一个小白,以为自己懂了点Linux知识,会搭建Linux各种服务就觉得自己牛的不要要的。在我们团队里面,我将使用了一台破电脑搭建Linux服务器,上面跑着Ftp服务存放着资源,ssh服务可以远程...

问题终结者
4分钟前
0
0
lombok的使用和原理

一、项目背景 在写Java程序的时候经常会遇到如下情形: 新建了一个Class类,然后在其中设置了几个字段,最后还需要花费很多时间来建立getter和setter方法 lombok项目的产生就是为了省去我们手...

颖辉小居
4分钟前
0
0
rsync至服务同步-系统日志-screen

rsync: 服务同步;配置文件:/etc/rsyncd.conf 默认端口:873 服务启动:rsync --daemon rsync -av /root/1.txt 192.168.1.2::test/2.txt (test为模块名称) /etc/rsync.conf配置样例: #指定...

ZHENG-JY
6分钟前
0
0
读取文件中内容转换成字符串

package com.lieni.ruyu.api.xmlTool; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.Unsuppo......

newdeng
6分钟前
0
0
《PHP和MySQL Web 开发》 第8章 设计Web数据库

LCL WARNING 这是我学习《PHP和MySQL Web 开发》的读书笔记,一些重要的知识点我会记录下来,当然只会写我觉得重要的。 如果有幸有人看到这个学习笔记了,你要结合着书看,不要光看这个笔记。...

十万猛虎下画山
13分钟前
0
0
Spring+jpaNo transactional EntityManager available

TransactionRequiredException: No transactional EntityManager availableEntityManager执行以下方法(refresh, persist, flush, joinTransaction, remove, merge) 都需要需要事务i......

wpfc
14分钟前
0
0
八幅漫画理解使用JSON Web Token设计单点登录系统

八幅漫画理解使用JSON Web Token设计单点登录系统 Sep 07, 2015 in Engineering 上次在《JSON Web Token - 在Web应用间安全地传递信息》中我提到了JSON Web Token可以用来设计单点登录系统。...

祖冲之
16分钟前
0
0
Spring框架中的设计模式(三)

Spring框架中的设计模式(三) 原创: 瑞查德-Jack 在之前的两篇文章中,我们看到了一些在Spring框架中实现的设计模式。这一次我们会发现这个流行框架使用的3种新模式。 本文将从描述两个创意...

瑞查德-Jack
19分钟前
1
0
[MicroPython]TPYBoard智能小车“飞奔的TPYBoard装甲一号”

智能小车作为现代的新发明,是以后的发展方向,他可以按照预先设定的模式在一个环境里自动的运作,不需要人为的管理,可应用于科学勘探等等的用途。智能小车能够实时显示时间、速度、里程,具...

bodasisiter
21分钟前
0
0
桌面虚拟化VDI(Virtual Desktop Infrastructure)

为了保证员工(客户)不把公司的资料复制、传输给别人。可以把员工平时办公放在服务器上做。所以使用桌面虚拟化。就是把一个服务器虚拟出很多桌面系统(如:windows)。 桌面虚拟化最大的优势...

王坤charlie
28分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部