还是那几句话:

学无止境,精益求精

十年河东,十年河西,莫欺少年穷

学历代表你的过去,能力代表你的现在,学习代表你的将来

废话不多说,直接进入正题:

今天公司总部要求各个分公司把短信接口对接上,所谓的短信接口其实就是GET或者Post请求,接到这个任务感觉好Easy。

但是真正写起来,你会发现各种各样的问题,比如请求报401错误,报400错误,报..等等各种意想不到的错误!总之,在这个过程中尝试了三个方法:

第一个方法如下(由于第一个方法封装的比较多,在此仅仅截图),如下:

小矩形内得POST方法,结果发现报400错误。

紧接着我又尝试了第二种方法(这种方法比较简单,一般的POST请求都可以完成)

第二种方法如下(2014年微信公众号开发中,好多请求我都用的这个方法):

public static string GetPage(string posturl, string postData)
{
//WX_SendNews news = new WX_SendNews();
//posturl: news.Posturl;
//postData:news.PostData;
System.IO.Stream outstream = null;
Stream instream = null;
StreamReader sr = null;
HttpWebResponse response = null;
HttpWebRequest request = null;
Encoding encoding = Encoding.UTF8;
byte[] data = encoding.GetBytes(postData);
// 准备请求...
try
{
// 设置参数
request = WebRequest.Create(posturl) as HttpWebRequest;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
outstream = request.GetRequestStream();
outstream.Write(data, , data.Length);
outstream.Close();
//发送请求并获取相应回应数据
response = request.GetResponse() as HttpWebResponse;
//直到request.GetResponse()程序才开始向目标网页发送Post请求
instream = response.GetResponseStream();
sr = new StreamReader(instream, encoding);
//返回结果网页(html)代码
string content = sr.ReadToEnd();
string err = string.Empty; return content;
}
catch (Exception ex)
{
string err = ex.Message;
return string.Empty;
}
}

结果这个方法报401错误。

无奈,又在Git Hub上找了个方法,如下:

/*
* Created by SharpDevelop.
* User: RedXu
* Date: 2015-04-16
* Time: 13:58
*
*/
using System;
using System.Net;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates; namespace RedXuCSharpClass
{
/// <summary>
/// Http操作类.
/// </summary>
public class HttpHelper
{
private const int ConnectionLimit = ;
//编码
private Encoding _encoding = Encoding.Default;
//浏览器类型
private string[] _useragents = new string[]{
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)",
"Mozilla/5.0 (Windows NT 6.1; rv:36.0) Gecko/20100101 Firefox/36.0",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20130401 Firefox/31.0"
}; private String _useragent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36";
//接受类型
private String _accept = "text/html, application/xhtml+xml, application/xml, */*";
//超时时间
private int _timeout = * ;
//类型
private string _contenttype = "application/x-www-form-urlencoded";
//cookies
private String _cookies = "";
//cookies
private CookieCollection _cookiecollection;
//custom heads
private Dictionary<string, string> _headers = new Dictionary<string, string>(); public HttpHelper()
{
_headers.Clear();
//随机一个useragent
_useragent = _useragents[new Random().Next(, _useragents.Length)];
//解决性能问题?
ServicePointManager.DefaultConnectionLimit = ConnectionLimit;
} public void InitCookie()
{
_cookies = "";
_cookiecollection = null;
_headers.Clear();
} /// <summary>
/// 设置当前编码
/// </summary>
/// <param name="en"></param>
public void SetEncoding(Encoding en)
{
_encoding = en;
} /// <summary>
/// 设置UserAgent
/// </summary>
/// <param name="ua"></param>
public void SetUserAgent(String ua)
{
_useragent = ua;
} public void RandUserAgent()
{
_useragent = _useragents[new Random().Next(, _useragents.Length)];
} public void SetCookiesString(string c)
{
_cookies = c;
} /// <summary>
/// 设置超时时间
/// </summary>
/// <param name="sec"></param>
public void SetTimeOut(int msec)
{
_timeout = msec;
} public void SetContentType(String type)
{
_contenttype = type;
} public void SetAccept(String accept)
{
_accept = accept;
} /// <summary>
/// 添加自定义头
/// </summary>
/// <param name="key"></param>
/// <param name="ctx"></param>
public void AddHeader(String key, String ctx)
{
//_headers.Add(key,ctx);
_headers[key] = ctx;
} /// <summary>
/// 清空自定义头
/// </summary>
public void ClearHeader()
{
_headers.Clear();
} /// <summary>
/// 获取HTTP返回的内容
/// </summary>
/// <param name="response"></param>
/// <returns></returns>
private String GetStringFromResponse(HttpWebResponse response)
{
String html = "";
try
{
Stream stream = response.GetResponseStream();
StreamReader sr = new StreamReader(stream, _encoding);
html = sr.ReadToEnd(); sr.Close();
stream.Close();
}
catch (Exception e)
{
Trace.WriteLine("GetStringFromResponse Error: " + e.Message);
} return html;
} /// <summary>
/// 检测证书
/// </summary>
/// <param name="sender"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="errors"></param>
/// <returns></returns>
private bool CheckCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
} /// <summary>
/// 发送GET请求
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public String HttpGet(String url)
{
return HttpGet(url, url);
} /// <summary>
/// 发送GET请求
/// </summary>
/// <param name="url"></param>
/// <param name="refer"></param>
/// <returns></returns>
public String HttpGet(String url, String refer)
{
String html;
try
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckCertificate);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.UserAgent = _useragent;
request.Timeout = _timeout;
request.ContentType = _contenttype;
request.Accept = _accept;
request.Method = "GET";
request.Referer = refer;
request.KeepAlive = true;
request.AllowAutoRedirect = true;
request.UnsafeAuthenticatedConnectionSharing = true;
request.CookieContainer = new CookieContainer();
//据说能提高性能
request.Proxy = null;
if (_cookiecollection != null)
{
foreach (Cookie c in _cookiecollection)
{
c.Domain = request.Host;
} request.CookieContainer.Add(_cookiecollection);
} foreach (KeyValuePair<String, String> hd in _headers)
{
request.Headers[hd.Key] = hd.Value;
} HttpWebResponse response = (HttpWebResponse)request.GetResponse();
html = GetStringFromResponse(response);
if (request.CookieContainer != null)
{
response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
} if (response.Cookies != null)
{
_cookiecollection = response.Cookies;
}
if (response.Headers["Set-Cookie"] != null)
{
string tmpcookie = response.Headers["Set-Cookie"];
_cookiecollection.Add(ConvertCookieString(tmpcookie));
} response.Close();
return html;
}
catch (Exception e)
{
Trace.WriteLine("HttpGet Error: " + e.Message);
return String.Empty;
}
} /// <summary>
/// 获取MINE文件
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public Byte[] HttpGetMine(String url)
{
Byte[] mine = null;
try
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckCertificate);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.UserAgent = _useragent;
request.Timeout = _timeout;
request.ContentType = _contenttype;
request.Accept = _accept;
request.Method = "GET";
request.Referer = url;
request.KeepAlive = true;
request.AllowAutoRedirect = true;
request.UnsafeAuthenticatedConnectionSharing = true;
request.CookieContainer = new CookieContainer();
//据说能提高性能
request.Proxy = null;
if (_cookiecollection != null)
{
foreach (Cookie c in _cookiecollection)
c.Domain = request.Host;
request.CookieContainer.Add(_cookiecollection);
} foreach (KeyValuePair<String, String> hd in _headers)
{
request.Headers[hd.Key] = hd.Value;
} HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream = response.GetResponseStream();
MemoryStream ms = new MemoryStream(); byte[] b = new byte[];
while (true)
{
int s = stream.Read(b, , b.Length);
ms.Write(b, , s);
if (s == || s < b.Length)
{
break;
}
}
mine = ms.ToArray();
ms.Close(); if (request.CookieContainer != null)
{
response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
} if (response.Cookies != null)
{
_cookiecollection = response.Cookies;
}
if (response.Headers["Set-Cookie"] != null)
{
_cookies = response.Headers["Set-Cookie"];
} stream.Close();
stream.Dispose();
response.Close();
return mine;
}
catch (Exception e)
{
Trace.WriteLine("HttpGetMine Error: " + e.Message);
return null;
}
} /// <summary>
/// 发送POST请求
/// </summary>
/// <param name="url"></param>
/// <param name="data"></param>
/// <returns></returns>
public String HttpPost(String url, String data)
{
return HttpPost(url, data, url);
} /// <summary>
/// 发送POST请求
/// </summary>
/// <param name="url"></param>
/// <param name="data"></param>
/// <param name="refer"></param>
/// <returns></returns>
public String HttpPost(String url, String data, String refer)
{
String html;
try
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckCertificate);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.UserAgent = _useragent;
request.Timeout = _timeout;
request.Referer = refer;
request.ContentType = _contenttype;
request.Accept = _accept;
request.Method = "POST";
request.KeepAlive = true;
request.AllowAutoRedirect = true;
request.CookieContainer = new CookieContainer();
//据说能提高性能
request.Proxy = null; if (_cookiecollection != null)
{
foreach (Cookie c in _cookiecollection)
{
c.Domain = request.Host;
if (c.Domain.IndexOf(':') > )
c.Domain = c.Domain.Remove(c.Domain.IndexOf(':'));
}
request.CookieContainer.Add(_cookiecollection);
} foreach (KeyValuePair<String, String> hd in _headers)
{
request.Headers[hd.Key] = hd.Value;
}
byte[] buffer = _encoding.GetBytes(data.Trim());
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, , buffer.Length);
request.GetRequestStream().Close(); HttpWebResponse response = (HttpWebResponse)request.GetResponse();
html = GetStringFromResponse(response);
if (request.CookieContainer != null)
{
response.Cookies = request.CookieContainer.GetCookies(request.RequestUri);
}
if (response.Cookies != null)
{
_cookiecollection = response.Cookies;
}
if (response.Headers["Set-Cookie"] != null)
{
string tmpcookie = response.Headers["Set-Cookie"];
_cookiecollection.Add(ConvertCookieString(tmpcookie));
} response.Close();
return html;
}
catch (Exception e)
{
Trace.WriteLine("HttpPost Error: " + e.Message);
return String.Empty;
}
} public string UrlEncode(string str)
{
StringBuilder sb = new StringBuilder();
byte[] byStr = _encoding.GetBytes(str);
for (int i = ; i < byStr.Length; i++)
{
sb.Append(@"%" + Convert.ToString(byStr[i], ));
} return (sb.ToString());
} /// <summary>
/// 转换cookie字符串到CookieCollection
/// </summary>
/// <param name="ck"></param>
/// <returns></returns>
private CookieCollection ConvertCookieString(string ck)
{
CookieCollection cc = new CookieCollection();
string[] cookiesarray = ck.Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
for (int i = ; i < cookiesarray.Length; i++)
{
string[] cookiesarray_2 = cookiesarray[i].Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
for (int j = ; j < cookiesarray_2.Length; j++)
{
string[] cookiesarray_3 = cookiesarray_2[j].Trim().Split("=".ToCharArray());
if (cookiesarray_3.Length == )
{
string cname = cookiesarray_3[].Trim();
string cvalue = cookiesarray_3[].Trim();
if (cname.ToLower() != "domain" && cname.ToLower() != "path" && cname.ToLower() != "expires")
{
Cookie c = new Cookie(cname, cvalue);
cc.Add(c);
}
}
}
} return cc;
} public void DebugCookies()
{
Trace.WriteLine("**********************BEGIN COOKIES*************************");
foreach (Cookie c in _cookiecollection)
{
Trace.WriteLine(c.Name + "=" + c.Value);
Trace.WriteLine("Path=" + c.Path);
Trace.WriteLine("Domain=" + c.Domain);
}
Trace.WriteLine("**********************END COOKIES*************************");
} }
}

结果又是没能跳出错误的怪圈,依然是401错误。

于是,我不得不温习下 C#  HttpClient  的相关方法

最后,还好,在公司的项目中有这种用到  HttpClient 的方法,于是抱着尝试的心里,作了测试,结果成功了!

本人写这篇博客也是做一个记录,方便自己以后用,也方便大家遇到 WebApi请求失败时,可以尝试上述的几种方法。

代码如下:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks; namespace KMHC.Infrastructure
{
public class SmsSendHelper
{
public string _appKey = "";
public string _category = "";
public string _templateNo = "";
public string _templateid = "";
public SmsSendHelper() { }
public async Task<SmsSendResult> Send(string phone, string sendContent)
{
var Model = BuildData(phone, sendContent);
SmsSendResult Result = new SmsSendResult();
var hh = new HttpClient() { BaseAddress = new Uri(SmsUri.SmsSendUri), Timeout = TimeSpan.FromMinutes() };
//Model 需要序列化的对象
var res = await hh.PostAsJsonAsync("", Model);
if (res.StatusCode == HttpStatusCode.OK)
{
var response = res.Content.ReadAsAsync<SmsSendResult>().Result;
return response;
}
return null;
} /// <summary>
/// 构建请求实体
/// </summary>
/// <param name="_phone"></param>
/// <param name="_sendContent"></param>
/// <returns></returns>
private object BuildData(string _phone, string _sendContent)
{
var para = new
{
appKey = _appKey,
category = _category,
templateNo = _templateNo,
templateid = _templateid,
phone = _phone,
sendContent = _sendContent
};
return para;
}
}
}
        [Route("test"), HttpGet, AllowAnonymous]
public async Task<IHttpActionResult> test()
{
SmsSendHelper Func = new SmsSendHelper();
var data =await Func.Send("181XXXX0152","你好!短信测试。");
return Ok(data);
}

需要引用如下命名空间:

总之,很简单,也很好用。

 @陈卧龙的博客

WebApi 异步请求(HttpClient)的更多相关文章

  1. .Net core webapi使用httpClient发送异步请求遇到TaskCanceledException: A task was canceled

    前言:本人最近较多使用.net core的项目,最近在使用httpClient发送请求的时候,遇到服务器处理时间较长时,就老是会报异常:TaskCanceledException: A task wa ...

  2. ASP.NET Core使用HttpClient的同步和异步请求

    using System; using System.Collections.Generic; using System.Collections.Specialized; using System.I ...

  3. C# ASP.NET Core使用HttpClient的同步和异步请求

    引用 Newtonsoft.Json // Post请求 public string PostResponse(string url,string postData,out string status ...

  4. Http和Https网络同步请求httpclient和异步请求async-http-client

    原文:https://blog.csdn.net/fengshizty/article/details/53100694 Http和https网络请求 主要总结一下使用到的网络请求框架,一种是同步网络 ...

  5. Http下的各种操作类.WebApi系列~通过HttpClient来调用Web Api接口

    1.WebApi系列~通过HttpClient来调用Web Api接口 http://www.cnblogs.com/lori/p/4045413.html HttpClient使用详解(java版本 ...

  6. c# 后台异步请求接口

    第一步:引用程序集:Systen.Net.Http 第一种方式: 异步 Get请求 HttpClient client = new HttpClient();            //client. ...

  7. Flutter 简介(事件、路由、异步请求)

    1. 前言 Flutter是一个由谷歌开发的开源移动应用软件开发工具包,用于为Android和iOS开发应用,同时也将是Google Fuchsia下开发应用的主要工具.其官方编程语言为Dart. 同 ...

  8. CAT中实现异步请求的调用链查看

    CAT简介 CAT(Central Application Tracking),是美团点评基于 Java 开发的一套开源的分布式实时监控系统.美团点评基础架构部希望在基础存储.高性能通信.大规模在线访 ...

  9. okhttp框架源码分析从同步&异步请求使用开始

    对于okhttp在如今项目中的普及程度已经不言而喻啦,基本上如今网络请求都会基于它去进行封装,而非前几年用Android的网络框架HttpURLConnection和Apache HttpClient ...

随机推荐

  1. Linux 时间及时区设置

    时间以及时区设置 by:授客 QQ:1033553122 1.首先确认使用utc还是local time. UTC(Universal Time Coordinated)=GMT(Greenwich ...

  2. ios开发GCD(2)-dispatch_semaphore_t信号量计数器

    思考:现在有多个线程异步执行,我们想要同时最多只能执行2个或n个,该怎么办? dispatch_semaphore_t 看代码解析: NSLog(@"开始"); dispatch_ ...

  3. 自定义ScrollView 实现上拉下拉的回弹效果--并且子控件中有Viewpager的情况

    onInterceptTouchEvent就是对子控件中Viewpager的处理:左右滑动应该让viewpager消费 public class MyScrollView extends Scroll ...

  4. (网页)JS和CSS不缓存方法,时间戳

    <link ..... href=".....css?time"+new Date()> <script type="text/javascript&q ...

  5. Python机器学习入门

    # NumPy Python科学计算基础包 import numpy as np # 导入numpy库并起别名为npnumpy_array = np.array([[1,3,5],[2,4,6]])p ...

  6. CRM JS

    注意事项:Xrm.Page中的方法使用的是实体.字段.关系的逻辑名称.窗体调试:contentIFrame.Xrm.Page.getControl("compositeControlPara ...

  7. Oracle 单引号 双引号 转义符 分隔符

    概述 单引号用来标记字符串 双引号用来标记识别对象名 以下使用会比较绕: 字符串中出现单引号.双引号: 表或字段等对象的别名(alias)中出单引号.双引号: 单引号.双引号与空格一起使用: 双引号 ...

  8. Python基础知识:if语句

    1.模拟网站确保用户名是否重复的方式,无视大小写,用到函数lower() #检查用户名是否重复 current_users=['admin','alex','lebran','kaobi','Jame ...

  9. WEB应用打成jar包全记录

    内容属原创,转载请注明出处 题外 由于项目的需求—不管是怎么产生的这个需求—总之,需要支持把一个web应用打成jar包供其他应用使用,这就有了下面的过程. 这个过程里用到了Spring和SpringM ...

  10. JavaScript的运行机制

    先来看一段代码然后再来详细的说明js的运行机制,下面的一段代码执行顺序是什么 console.log(1); setTimeout(function () { console.log(2); }, 0 ...