服务端发post请求产生的编码问题
最近在做一个功能,大概功能是这样的,供应商提供http接口给我们,然后我们抓取供应商的数据保存到数据库,问题在于他们编码格式是gb2312的,而我们是utf-8。
大家可能会有个误区,post请求是无需编码的,其实不然,只要在http请求头中 "Content-Type"为"application/x-www-form-urlencoded,调接口前都会用当前编码格式urlencode。所以如果前端post数据到后端时,前端是gb2312编码格式,后端是utf-8,只需在Content-Type中设置,application/x-www-form-urlencoded;charset=utf-8。
而我们是服务端直接调接口,而我用的是restsharp
var request = new RestRequest(Method.POST); request.RequestFormat = DataFormat.Json; request.AddBody(model); var client = new RestClient("http://localhost:2290/Interface/Index"); var response = client.Execute(request); return response.Content;
翻阅文档,这期间会自动urlencode。。。
后来尝试设置web.config,设置默认编码格式,编码问题依然解决不了,有种冲动想去看restsharp的源码,可惜时间来不及啊。。。。(有时间一定要看下)
<globalization requestEncoding="gb2312" responseEncoding="gb2312"/>
最后终于找到了解决方案,用.net 源生的方式 httprequest
/// <summary> /// 创建POST方式的HTTP请求 /// </summary> /// <param name="url">请求的URL</param> /// <param name="parameters">随同请求POST的参数名称及参数值字典</param> /// <param name="timeout">请求的超时时间</param> /// <param name="userAgent">请求的客户端浏览器信息,可以为空</param> /// <param name="requestEncoding">发送HTTP请求时所用的编码</param> /// <param name="cookies">随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空</param> /// <returns></returns> public static HttpWebResponse CreatePostHttpResponse(string url, IDictionary<string, string> parameters, int? timeout, string userAgent, Encoding requestEncoding, CookieCollection cookies) { if (string.IsNullOrEmpty(url)) { throw new ArgumentNullException("url"); } if (requestEncoding == null) { throw new ArgumentNullException("requestEncoding"); } HttpWebRequest request = null; //如果是发送HTTPS请求 if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); request = WebRequest.Create(url) as HttpWebRequest; request.ProtocolVersion = HttpVersion.Version10; } else { request = WebRequest.Create(url) as HttpWebRequest; } request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; if (!string.IsNullOrEmpty(userAgent)) { request.UserAgent = userAgent; } else { request.UserAgent = DefaultUserAgent; } if (timeout.HasValue) { request.Timeout = timeout.Value; } if (cookies != null) { request.CookieContainer = new CookieContainer(); request.CookieContainer.Add(cookies); } //如果需要POST数据 if (!(parameters == null || parameters.Count == 0)) { StringBuilder buffer = new StringBuilder(); int i = 0; foreach (string key in parameters.Keys) { if (i > 0) { buffer.AppendFormat("&{0}={1}", key, parameters[key]); } else { buffer.AppendFormat("{0}={1}", key, parameters[key]); } i++; } byte[] data = requestEncoding.GetBytes(buffer.ToString()); using (Stream stream = request.GetRequestStream()) { stream.Write(data, 0, data.Length); } } return request.GetResponse() as HttpWebResponse; }
调用如下:
IDictionary<string, string> parameters = new Dictionary<string, string>(); parameters.Add("RequestJson", jsonstr); HttpWebResponse response = HttpWebResponseUtility.CreatePostHttpResponse(url, parameters, null, null, Encoding.GetEncoding("GB2312"), null); using (StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8)) { strres = reader.ReadToEnd(); }