啊,好久没写过博客了_(:з」∠)_
之前给一个大佬做有赞应用时候遇到了post收发的问题,其实实现起来很简单的。无奈网上关于这方面的资料很少,特此整理一下,希望帮助有需要的人_(:з」∠)_
发送
直接上代码了,关键的地方我加了注释,应该不难理解。
C#提供了相关的API,很方便。这段代码可以直接拿去用_(:з」∠)_
大致步骤就是创建Request-填充信息-发送。
/// <summary>
/// Post提交数据
/// </summary>
/// <param name="postUrl">URL</param>
/// <param name="paramData">参数</param>
/// <returns></returns>
string PostWebRequest(string postUrl, string paramData)
{
string ret = string.Empty;
try
{
byte[] byteArray = Encoding.UTF8.GetBytes(paramData);
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(postUrl));
// 提交方法,POST/GET等
webReq.Method = "POST";
// ContentType
webReq.ContentType = "application/x-www-form-urlencoded";
webReq.ContentLength = byteArray.Length;
Stream newStream = webReq.GetRequestStream();
//写入参数
newStream.Write(byteArray, 0, byteArray.Length);
newStream.Close();
HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
ret = sr.ReadToEnd();
sr.Close();
response.Close();
newStream.Close();
}
catch (Exception ex)
{
return ex.Message;
}
return ret;
}
接收
接收消息模块我分了两部分,一是主体,如何调用api进行监听。这部分需要另开一个线程来处理。
/// <summary>
/// 监听post消息,在收到消息后发送响应消息。
/// 建议使用死循环反复监听,且开启一个线程执行该方法。
/// </summary>
void ListenWebRequest()
{
// string url= "需要监听的url范围";
// 示例:(这里有个坑,见下文)
string url = "http://127.0.0.1:2333";
try
{
HttpListener listener = new HttpListener();
listener.Prefixes.Add(url);
// 开始监听端口,接收客户端请求
listener.Start();
// 阻塞主函数至接收到一个客户端请求为止
// 也可以使用listener.BeginGetContext()异步监听
HttpListenerContext context = listener.GetContext();
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
// msg即为body内容
string msg = GetBodyString(request);
// 通过QueryString索引获取post参数
string sample = request.QueryString["sample"];
// 收到信息后返回数据
string responseString = "响应数据";
response.StatusCode = 200;
// header头信息
response.Headers.Add("Access-Control-Allow-Origin", "*");
// contentType 类型
response.ContentType = "application/json";
response.ContentEncoding = System.Text.Encoding.UTF8;
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
Stream output = response.OutputStream;
output.Write(buffer, 0, buffer.Length);
output.Close();
listener.Stop();
listener.Close();
}
catch (Exception ex)
{
// TODO
}
}
第二部分,由于接收到的post消息中body内容是以流格式的,还需要将其转换为string。
/// <summary>
/// 将body内容解析为String。
/// </summary>
/// <returns>The body string.</returns>
/// <param name="request">Request.</param>
string GetBodyString(HttpListenerRequest request)
{
string result = null;
using (System.IO.Stream body = request.InputStream) // here we have data
{
using (System.IO.StreamReader reader = new System.IO.StreamReader(body, request.ContentEncoding))
{
result = reader.ReadToEnd();
}
}
if (string.IsNullOrEmpty(result))
{
// TODO 读取到空消息
}
else
{
// TODO 成功读取消息
}
return result;
}
推荐一个post测试工具
Restlet Client – REST API Testing
谷歌浏览器插件:下载链接(需要翻墙)
炒鸡好用!
碎碎念
就是在接收方法那绑定的url,我当时用的腾讯云的服务器(window系统)测试的。是这样的,
如果url是localhost或127.0.0.1,在服务器本机测试一切正常。但如果从外网向其post数据,会报400或405错误。
如果url是服务器外网IP呢,干脆直接抛异常,好像是无法绑定。
最后尝试了下将url改成内网IP,一切OK。不过我还是不知道是什么原因_(:з」∠)_
3 comments
收藏了_(:з」∠)_
谢谢_(:з」∠)_
:redface: