最近在做一个功能,大概功能是这样的,供应商提供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();
}