解析C#网络编程中的Http请求

本篇分享简单介绍C#中的Http请求,前几天帮朋友的项目封装ApiHelper,我粗糙的结果就如下,想想我真的是差的太远了。还有一位架构师也在封装这个Helper , 所以最后的结果当然是使用大牛的封装,这篇分享后,准备学习下他的封装,配置,错误处理机制等思想。不过这次也使我对C#网络编程了解的更多,算是一次学习经历吧。真心喜欢和老司机合作,下一阶段将会持续跟这位朋友学习项目底层的封装,和他谦虚的态度,有这样的机会也是幸运的。

你可以将其封装成自己的HttpHelper,经朋友建议,统一Http请求的入参和出参。在HttpClient方面也参考了dudu的关于httpclient预热的文章。C#中HttpClient使用注意:预热与长连接。

为了做到统一入参和出参,定义了Req<T>泛型类和Resp<T>泛型类。你可以根据自己的需要进行拓展。

public class Req<T>
    {
        /// <summary>
        /// 传入数据
        /// </summary>
        public T Input { get; set; }
        /// <summary>
        /// 请求地址
        /// </summary>
        public string Url { get; set; }
    }
public class Resp<T>
    {
        /// <summary>
        /// 错误消息
        /// </summary>
        public string ErrorMsg { get; set; }
        /// <summary>
        /// 状态码
        /// </summary>
        public int StatusCode { get; set; }
        /// <summary>
        /// 返回数据
        /// </summary>
        public T RespData { get; set; }
    }

虽然保持了httpClient对象复用,但需要注意的是,在设置了httpClient,并且发生了一次请求之后,不能再对其属性进行重新设置。这也正是我又定义了一个fileClient的理由。

  #region HttpClient版本
         private static readonly string _baseAddress = ConfigurationManager.AppSettings["api-server"];//配置BaseUrl eg.http://localhost:1234
        private static readonly HttpClient _httpClient;
       private static readonly HttpClient _fileClient;
         static ApiHelper()
         {
              #region 初始化和预热 httpClient
             _httpClient = new HttpClient();
            _httpClient.BaseAddress = new Uri(_baseAddress);
             _httpClient.Timeout = TimeSpan.FromMilliseconds(2000);
            _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");//application/xml  想Accept的数据格式
            _httpClient.SendAsync(new HttpRequestMessage
            {
                Method = new HttpMethod("HEAD"),
                 RequestUri = new Uri(_baseAddress + "/api/test/HttpClientHot")
             })
             .Result.EnsureSuccessStatusCode();
             #endregion

            #region 初始化和预热 fileClient
            _fileClient = new HttpClient();
             _fileClient.BaseAddress = new Uri(_baseAddress + "/api/test/HttpClientHot");
            _fileClient.MaxResponseContentBufferSize = 256000;
            #endregion
        }
         /// <summary>
         /// http Get请求
        /// </summary>
         /// <typeparam name="T">入参类型</typeparam>
        /// <typeparam name="TResult">出参类型</typeparam>
        /// <param name="req">入参对象</param>
        /// <returns></returns>
         public static async Task<Resp<TResult>> GetAsync<T, TResult>(Req<T> req)
        {
            try
                var result =await _httpClient.GetAsync(req.Url).Result.Content.ReadAsStringAsync();
                return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) };
             }
            catch(Exception ex)
              }
                 return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>("") };

       }
          /// <summary>
          ///  http Post请求
          /// </summary>
          /// <typeparam name="T">入参类型</typeparam>
          /// <typeparam name="TResult">出参类型</typeparam>
          /// <param name="req">入参对象</param>
          /// <returns></returns>
          public static async Task<Resp<TResult>> PostAsJsonAsync<T, TResult>(Req<T> req)
              var result = await _httpClient.PostAsJsonAsync(req.Url, req.Input).Result.Content.ReadAsStringAsync();
              return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) };
          }
         /// 上传文件
         /// <typeparam name="T"></typeparam>
         /// <typeparam name="TResult"></typeparam>
         /// <param name="req"></param>
         /// <param name="filePath"></param>
        public static async Task<Resp<TResult>> SendFile<T, TResult>(Req<T> req, string filePath)//D:\\white.jpg
             //_fileClient.DefaultRequestHeaders.Add("user-agent", "User-Agent    Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; MALNJS; rv:11.0) like Gecko");//设置请求头
            // 读文件流
             FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
              HttpContent fileContent = new StreamContent(fs);//为文件流提供的HTTP容器
             fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");//设置媒体类型
            MultipartFormDataContent mulContent = new MultipartFormDataContent("----");//创建用于可传递文件的容器
              string fileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
             mulContent.Add(fileContent, "form", fileName);//第二个参数是表单名,第三个是文件名。
              HttpResponseMessage response = await _fileClient.PostAsync(req.Url, mulContent);
             response.EnsureSuccessStatusCode();
             string result = await response.Content.ReadAsStringAsync();
             return new Resp<TResult>() { Data = JsonHelper.JsonDeserialize<TResult>(result) };
         }
         /// 下载
        /// <param name="url"></param>
         /// <returns></returns>
        public static async Task<Resp<byte[]>> HttpDownloadData<T>(Req<T> req)
             var byteres = await _fileClient.GetByteArrayAsync(req.Url);
             return new Resp<byte[]>() { Data = byteres };
        #endregion
 }

另外分享下HttpWebRequest来实现的请求。HttpWebRequest需要你自行设置很多内容,当然这也证明其内容丰富。下面代码包含了post,get,以及上传。

/// <summary>
        /// Post Http请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="postData">传输数据</param>
        /// <param name="timeout">超时时间</param>
        /// <param name="contentType">媒体格式</param>
        /// <param name="encode">编码</param>
        /// <returns>泛型集合</returns>
        public static List<T> PostAndRespList<T>(string url, string postData, int timeout = 5000, string contentType = "application/json;", string encode = "UTF-8")
        {
            if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode) && !string.IsNullOrEmpty(contentType) && postData != null)
            {
                // webRequest.Headers.Add("Authorization", "Bearer " + "SportApiAuthData");
                HttpWebResponse webResponse = null;
                Stream responseStream = null;
                Stream requestStream = null;
                StreamReader streamReader = null;
                try
                {
                    string respstr = GetStreamReader(url, responseStream, requestStream, streamReader, webResponse, timeout, encode, postData, contentType);
                    return JsonHelper.JsonDeserialize<List<T>>(respstr);

                }
                catch (Exception ex)
                {

                }
                finally
                {
                    if (responseStream != null) responseStream.Dispose();
                    if (webResponse != null) webResponse.Dispose();
                    if (requestStream != null) requestStream.Dispose();
                    if (streamReader != null) streamReader.Dispose();
                }
            }
            return null;
        }

        /// <summary>
        /// Post Http请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="postData">传输数据</param>
        /// <param name="timeout">超时时间</param>
        /// <param name="contentType">媒体格式</param>
        /// <param name="encode">编码</param>
        /// <returns>泛型集合</returns>
        public static T PostAndRespSignle<T>(string url, int timeout = 5000, string postData = "", string contentType = "application/json;", string encode = "UTF-8")
        {
            if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode) && !string.IsNullOrEmpty(contentType) && postData != null)
            {
                // webRequest.Headers.Add("Authorization", "Bearer " + "SportApiAuthData");
                HttpWebResponse webResponse = null;
                Stream responseStream = null;
                Stream requestStream = null;
                StreamReader streamReader = null;
                try
                {
                    string respstr = GetStreamReader(url, responseStream, requestStream, streamReader, webResponse, timeout, encode, postData, contentType);
                    return JsonHelper.JsonDeserialize<T>(respstr);
                }
                catch (Exception ex)
                {

                }
                finally
                {
                    if (responseStream != null) responseStream.Dispose();
                    if (webResponse != null) webResponse.Dispose();
                    if (requestStream != null) requestStream.Dispose();
                    if (streamReader != null) streamReader.Dispose();
                }
            }
            return default(T);
        }

        /// <summary>
        /// Post Http请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="postData"></param>
        /// <param name="timeout"></param>
        /// <param name="contentType"></param>
        /// <param name="encode"></param>
        /// <returns>响应流字符串</returns>
        public static string PostAndRespStr(string url, int timeout = 5000, string postData = "", string contentType = "application/json;", string encode = "UTF-8")
        {
            if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode) && !string.IsNullOrEmpty(contentType) && postData != null)
            {
                HttpWebResponse webResponse = null;
                Stream responseStream = null;
                Stream requestStream = null;
                StreamReader streamReader = null;
                try
                {

                    return GetStreamReader(url, responseStream, requestStream, streamReader, webResponse, timeout, encode, postData, contentType);
                }
                catch (Exception ex)
                {

                }
                finally
                {
                    if (responseStream != null) responseStream.Dispose();
                    if (webResponse != null) webResponse.Dispose();
                    if (requestStream != null) requestStream.Dispose();
                    if (streamReader != null) streamReader.Dispose();
                }
            }
            return null;
        }

        private static string GetStreamReader(string url, Stream responseStream, Stream requestStream, StreamReader streamReader, WebResponse webResponse, int timeout, string encode, string postData, string contentType)
        {
            byte[] data = Encoding.GetEncoding(encode).GetBytes(postData);
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
            SetAuth(webRequest);
            webRequest.Method = "POST";
            webRequest.ContentType = contentType + ";" + encode;
            webRequest.ContentLength = data.Length;
            webRequest.Timeout = timeout;
            requestStream = webRequest.GetRequestStream();
            requestStream.Write(data, 0, data.Length);
            webResponse = (HttpWebResponse)webRequest.GetResponse();
            responseStream = webResponse.GetResponseStream();
            if (responseStream == null) { return ""; }
            streamReader = new StreamReader(responseStream, Encoding.GetEncoding(encode));
            return streamReader.ReadToEnd();
        }

        /// <summary>
        /// Post文件流给指定Url
        /// </summary>
        /// <param name="url">url</param>
        /// <param name="filePath">文件路径</param>
        /// <returns>响应流字符串</returns>
        public static string PostFile(string url, string filePath, string contentType = "application/octet-stream", string encode = "UTF-8")
        {
            if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode) && !string.IsNullOrEmpty(contentType) && !string.IsNullOrEmpty(filePath))
            {

                Stream requestStream = null;
                Stream responseStream = null;
                StreamReader streamReader = null;
                FileStream fileStream = null;
                try
                {
                    // 设置参数
                    HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;
                    SetAuth(webRequest);
                    webRequest.AllowAutoRedirect = true;
                    webRequest.Method = "POST";
                    string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线
                    webRequest.ContentType = "multipart/form-data;charset=" + encode + ";boundary=" + boundary;
                    byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");//消息开始
                    byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");//消息结尾
                    var fileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
                    //请求头部信息
                    string postHeader = string.Format("Content-Disposition:form-data;name=\"media\";filename=\"{0}\"\r\nContent-Type:{1}\r\n\r\n", fileName, contentType);
                    byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);
                    fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                    byte[] fileByteArr = new byte[fileStream.Length];
                    fileStream.Read(fileByteArr, 0, fileByteArr.Length);
                    fileStream.Close();
                    requestStream = webRequest.GetRequestStream();
                    requestStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
                    requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
                    requestStream.Write(fileByteArr, 0, fileByteArr.Length);
                    requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
                    requestStream.Close();
                    responseStream = webRequest.GetResponse().GetResponseStream();//发送请求,得到响应流
                    if (responseStream == null) return string.Empty;
                    streamReader = new StreamReader(responseStream, Encoding.UTF8);
                    return streamReader.ReadToEnd();
                }
                catch (Exception ex)
                {

                }
                finally
                {

                }
            }
            return null;

        }

        /// <summary>
        /// Get http请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="timeout">超时时间</param>
        /// <param name="encode">编码</param>
        /// <returns>返回单个实体</returns>
        public static T GetSingle<T>(string url, int timeout = 5000, string encode = "UTF-8")
        {
            //HttpWebRequest对象
            //HttpClient->dudu 调用预热处理
            //Stream—>Model

            if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode))
            {
                Stream responseStream = null;
                StreamReader streamReader = null;
                WebResponse webResponse = null;
                try
                {
                    string respStr = GetRespStr(url, responseStream, streamReader, webResponse, timeout, encode);
                    return JsonHelper.JsonDeserialize<T>(respStr);
                }
                catch (Exception ex)
                {

                }
                finally
                {
                    if (responseStream != null) responseStream.Dispose();
                    if (streamReader != null) streamReader.Dispose();
                    if (webResponse != null) webResponse.Dispose();
                }
            }
            return default(T);
        }

        /// <summary>
        ///  Get http请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="timeout"></param>
        /// <param name="encode"></param>
        /// <returns>响应流字符串</returns>
        public static string GetResponseString(string url, int timeout = 5000, string encode = "UTF-8")
        {
            if (!string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(encode))
            {
                Stream responseStream = null;
                StreamReader streamReader = null;
                WebResponse webResponse = null;
                try
                {
                    return GetRespStr(url, responseStream, streamReader, webResponse, timeout, encode);
                }
                catch (Exception ex)
                {

                }
                finally
                {
                    if (responseStream != null) responseStream.Dispose();
                    if (streamReader != null) streamReader.Dispose();
                    if (webResponse != null) webResponse.Dispose();
                }
            }
            return null;
        }

        private static string GetRespStr(string url, Stream responseStream, StreamReader streamReader, WebResponse webResponse, int timeout, string encode)
        {
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
            webRequest.Method = "GET";
            webRequest.Timeout = timeout;
            webResponse = webRequest.GetResponse();
            responseStream = webResponse.GetResponseStream();
            if (responseStream == null) { return ""; }
            streamReader = new StreamReader(responseStream, Encoding.GetEncoding(encode));
            return streamReader.ReadToEnd();
         }

到此这篇关于C#网络编程中的Http请求的文章就介绍到这了,更多相关C#网络编程Http请求内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C#网络编程之Socket编程

    目录 一:什么是SOCKET 套接字分类 二:SOCKET相关概念 1.端口 2.协议 2.1 TCP: 2.2 UDP 三:socket一般应用模式: 四:SOCKET通信基本流程图: 服务器端: 客户端: 五:示例程序 一:什么是SOCKET socket的英文原义是“孔”或“插座”.作为进程通信机制,取后一种意思.通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄(其实就是两个程序通信用的).socket非常类似于电话插座.以一个电话网为例:电话的通话双方相当于相互通信的2个

  • c# 网络编程之http

    一.概述 本文目的是通过C#代码提供一个HTTP服务,正常情况下如果我们需要向外界提供HTTP服务,常规做法就是通过ASP.NET来实现,有时我们的应用程序或Windows服务需要向外提供一些简单的HTTP服务就可以自己实现,从而避免部署IIS增加系统复杂性.这里必须强调是一些简单的应用,如果应用比较复杂,涉及到路径解析HTML解析等,还是用WEB方式实现比较靠谱. 将HTTP和UDP.TCP放在同一个系列实际上有一点不合适,因为UDP.TCP属于传输层协议,HTTP属于应用层协议,希望读者首先

  • C#网络编程中常用特性介绍

    特性一:委托 委托是C#语言中特有的概念,相当于C/C++中的函数指针,与C/C++中函数指针的不同之处是:委托是面向对象的.类型安全的和保险的,是引用类型.因此,对委托的使用要 “先定义.后声明,接着实例化.然后作为参数传递给方法,最后才能使用”. 1.定义委托使用关键字delegate: delegate  void SomeDelegate(type1 para1,......typen paran); 2.声明委托: SomeDelegate  d; 3.实例化委托: d=new Som

  • 解析C#网络编程中的Http请求

    本篇分享简单介绍C#中的Http请求,前几天帮朋友的项目封装ApiHelper,我粗糙的结果就如下,想想我真的是差的太远了.还有一位架构师也在封装这个Helper , 所以最后的结果当然是使用大牛的封装,这篇分享后,准备学习下他的封装,配置,错误处理机制等思想.不过这次也使我对C#网络编程了解的更多,算是一次学习经历吧.真心喜欢和老司机合作,下一阶段将会持续跟这位朋友学习项目底层的封装,和他谦虚的态度,有这样的机会也是幸运的. 你可以将其封装成自己的HttpHelper,经朋友建议,统一Http

  • 简单介绍Java网络编程中的HTTP请求

    HTTP请求的细节--请求行   请求行中的GET称之为请求方式,请求方式有:POST.GET.HEAD.OPTIONS.DELETE.TRACE.PUT,常用的有: GET. POST 用户如果没有设置,默认情况下浏览器向服务器发送的都是get请求,例如在浏览器直接输地址访问,点超链接访问等都是get,用户如想把请求方式改为post,可通过更改表单的提交方式实现. 不管POST或GET,都用于向服务器请求某个WEB资源,这两种方式的区别主要表现在数据传递上:如果请求方式为GET方式,则可以在请

  • 解析Java线程编程中的线程安全与synchronized的使用

    一.什么时候会出现线程安全问题? 在单线程中不会出现线程安全问题,而在多线程编程中,有可能会出现同时访问同一个资源的情况,这种资源可以是各种类型的的资源:一个变量.一个对象.一个文件.一个数据库表等,而当多个线程同时访问同一个资源的时候,就会存在一个问题: 由于每个线程执行的过程是不可控的,所以很可能导致最终的结果与实际上的愿望相违背或者直接导致程序出错. 举个简单的例子: 现在有两个线程分别从网络上读取数据,然后插入一张数据库表中,要求不能插入重复的数据. 那么必然在插入数据的过程中存在两个操

  • Java网络编程教程之设置请求超时的方法

    一.引言 随着企业系统的发展,应用多采用分布式结构,严重依赖于网络的稳定性.但由于网络天生的不稳定性,系统开发过程中需要考虑网络不稳定情况下如何保证应用的鲁棒性. 设置网络超时是其中一种保证应用健壮性的手段. 设置网络超时设置后,请求在设定时间能未完成将被强制终止,保证程序不出现无限制的线程阻塞情况,有效的提高了应用的可用性. 下面话不多说了,来一起看看详细的介绍吧. 二.未设置超时与设置超时情况对比 1. 网络请求图例: 网络请求超时案例 2. 设置超时时间后,请求图例: 网络请求超时案例-设

  • 实例解析Java单例模式编程中对抽象工厂模式的运用

    定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类. 类型:创建类模式 类图: 抽象工厂模式与工厂方法模式的区别         抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象.他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构:而抽象工厂模式则是针对的多个产品等级结构.在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同

  • 实例解析C#设计模式编程中简单工厂模式的使用

    简单工厂模式的介绍 说到简单工厂,自然的第一个疑问当然就是什么是简单工厂模式了? 在现实生活中工厂是负责生产产品的,同样在设计模式中,简单工厂模式我们也可以理解为负责生产对象的一个类, 我们平常编程中,当使用"new"关键字创建一个对象时,此时该类就依赖与这个对象,也就是他们之间的耦合度高,当需求变化时,我们就不得不去修改此类的源码,此时我们可以运用面向对象(OO)的很重要的原则去解决这一的问题,该原则就是--封装改变,既然要封装改变,自然也就要找到改变的代码,然后把改变的代码用类来封

  • java网络编程中向指定URL发送GET POST请求示例

    复制代码 代码如下: import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintWriter;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLConnection;import jav

  • 解析C#多线程编程中异步多线程的实现及线程池的使用

    0.线程的本质 线程不是一个计算机硬件的功能,而是操作系统提供的一种逻辑功能,线程本质上是进程中一段并发运行的代码,所以线程需要操作系统投入CPU资源来运行和调度. 1.多线程: 使用多个处理句柄同时对多个任务进行控制处理的一种技术.据博主的理解,多线程就是该应用的主线程任命其他多个线程去协助它完成需要的功能,并且主线程和协助线程是完全独立进行的.不知道这样说好不好理解,后面慢慢在使用中会有更加详细的讲解. 2.多线程的使用: (1)最简单.最原始的使用方法:Thread oGetArgThre

  • Python网络编程中urllib2模块的用法总结

    一.最基础的应用 import urllib2 url = r'http://www.baidu.com' html = urllib2.urlopen(url).read() print html 客户端与服务器端通过request与response来沟通,客户端先向服务端发送request,然后接收服务端返回的response urllib2提供了request的类,可以让用户在发送请求前先构造一个request的对象,然后通过urllib2.urlopen方法来发送请求 import ur

随机推荐