一些简单的Post方式WebApi接收参数和传递参数的方法及总结
原文地址:https://www.zhaimaojun.top/Note/5475297(我自己的博客网站)
各种Post方式上传参数到服务器,服务器接收各种参数的示例
webapi可以说是很常用了,内容也很多,get方式用的多而且很简单,没有说的必要了,但是post方式中,数据从数据体中提取是总是会遇到一些妖魔现象。对此,就我知道的我说一些吧。
作为懒汉,一切繁琐的代码,逻辑,都是累赘,都是看不顺眼的,拖泥带水的代码,逻辑就像强迫症眼里的不规则摆放,总是要解决掉心里才能舒坦的懒。天天幻想着一条代码解决所有问题~
最近有点想注册个bilibili的up主发点代码讲解的视频,我想我能将的比较细致,码字太累了,不符合懒汉的生活习惯,就这短短的文章也是码了一下午才写完的,所以还是讲话来的快,还不耽误玩游戏。
webapi的url组成我就不详细说了,一般都是http://XXX/api/控制器名?参数名=参数值&参数名=参数值
第一种:
[httppost]
public string Get(string p1,[frombody]string p2){
return p1+p2;
}
var p2 = "param2";//p2是需要post传输的
var url = "http://XXX/api/XXX?p1=param1";//p2是来自于post体,所以不再url中
var req= (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";//你没有看错,就是这个
var bts = Encoding.Utf8.GetBytes("="+p2);//划重点!!post方式中application/x-www-form-urlencoded传输方式下,frombody的参数只能有一个!而在body中你要是用key=value方式传递参数,那么接收端收到的全都是null。
req.ContentLenth = bts.Lenth;//划重点!!post方式必须设置这个值
var st = req.GetResquestStream();
st.Write(bts,0,bts.Lenth);//划重点!!post方式必须要往body中写入数据
var res= (HttpWebResponse)req.GetResponse();
var url = "http://XXX/api/XX?p1=param1"
var p2 = "param2"
$.post(url, "="+p2, function(res){
alert(res);
});
var p2 = "param2";
wx.request({
url: 'http://XXX/api/XX?p1=param1',
method: 'POST',
header: {'content-type': 'application/x-www-form-urlencoded'},//或者不写这行
data: "=" + p2,
success(re){
console.log(re);
}
});
第二种:
[httppost]
public string Post(string p1){
var p2 = HttpContext.Current.Request.Form["p2"];
var p3 = HttpContext.Current.Request.Form["p3"];
if(HttpContext.Current.Request.Files.Lenth > 0){
var fs = HttpContext.Current.Request.Files[0];
fs.SaveAs(HttpContext.Current.Server.MapPath("~/data.txt"));
}
return p1+p2+p3;//上传的混合参数
}
c#发送参数:
private string UploadFileAndParams(string serverIp, int serverPort, string rowurl, string filename, Dictionary<string, string> otherparams)
{
try
{
//打开socket连接
Socket httpsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
httpsocket.Connect(serverIp, serverPort);
//计算得出总的一个请求
//请求的头部
string httprequestheader = "POST " + rowurl + " HTTP/1.1\r\n";
httprequestheader += "Host: " + serverIp + ":" + serverPort + "\r\n";
//httprequestheader += "Content-Length: " + "\r\n";//计算并添加数据长度,这里的数据长度是总的长度
httprequestheader += "Content-Type: multipart/form-data; boundary=OCqxMF6-JxtxoMDHmoG5W5eY9MGRsTBp\r\n";
httprequestheader += "Connection: Keep-Alive\r\n";
//发送文件
string httpFileheader = "--OCqxMF6-JxtxoMDHmoG5W5eY9MGRsTBp\r\n";
httpFileheader += "Content-Disposition: attachment; name=text; filename=" + Path.GetFileName(filename) + "\r\n";
httpFileheader += "Content-Type: application/octet-stream\r\n";
httpFileheader += "Content-Transfer-Encoding: binary\r\n";
httpFileheader += "\r\n";
byte[] Bfileheader = Encoding.UTF8.GetBytes(httpFileheader);
//这里需要发送文件的内容,二进制
FileStream localfile = new FileStream(filename, FileMode.Open);
//发送其他参数
var lBParamheaders = new List<byte[]>();
foreach (var item in otherparams)
{
string paramstr = "--OCqxMF6-JxtxoMDHmoG5W5eY9MGRsTBp\r\n";
paramstr += "Content-Disposition: form-data; name=" + item.Key + "\r\n";
paramstr += "Content-Type: text/plain; charset=UTF-8\r\n";
paramstr += "\r\n";
paramstr += item.Value + "\r\n";
lBParamheaders.Add(Encoding.UTF8.GetBytes(paramstr));
}
byte[] Bendbody = Encoding.UTF8.GetBytes("--OCqxMF6-JxtxoMDHmoG5W5eY9MGRsTBp--\r\n");
//统计总长度
long lenth = Bfileheader.Length + localfile.Length + Bendbody.Length + 2;
foreach (var item in lBParamheaders)
lenth += item.Length;
httprequestheader += "Content-Length: " + lenth + "\r\n";//计算并添加数据长度,这里的数据长度是总的长度
httprequestheader += "\r\n";
byte[] Brequestheader = Encoding.UTF8.GetBytes(httprequestheader);
//开始发送请求
string sv = Encoding.UTF8.GetString(Brequestheader);
httpsocket.Send(Brequestheader);//发送头
sv += Encoding.UTF8.GetString(Bfileheader);
httpsocket.Send(Bfileheader);//发送文件头
//发送文件
for (long i = 0; i < localfile.Length;)
{
int len = ((localfile.Length - i) > 30000) ? 30000 : (int)(localfile.Length - i);
byte[] bt = new byte[len];
localfile.Read(bt, 0, len);
sv += Encoding.UTF8.GetString(bt);
httpsocket.Send(bt);
i += len;
}
sv += "\r\n";
httpsocket.Send(Encoding.UTF8.GetBytes("\r\n"));
//发送其他参数
foreach (var item in lBParamheaders)
{
sv += Encoding.UTF8.GetString(item);
httpsocket.Send(item);
}
sv += Encoding.UTF8.GetString(Bendbody);
httpsocket.Send(Bendbody);
//等待服务器返回结果:
byte[] result = new byte[30000];
int reslen = httpsocket.Receive(result);
//处理并返回结果
string resultstr = Encoding.UTF8.GetString(result, 0, reslen);
int idex = resultstr.IndexOf("\r\n\r\n");
string resstr = resultstr.Substring(idex);
localfile.Close();
httpsocket.Close();
return resstr;
}
catch (Exception ex)
{
return ex.Message;
}
}
//使用:
var pms = new Dictionary<string, string>();
pms.Add("p2","param2");
pms.Add("p3","param3");
var result = UploadFileAndParam("192.168.1.1",8088,"/api/XX?p1=param1","指定一个本地要上传的文件名",pms);
ajax提交参数(html):
<form method="post" action="/api/XXX?p1=param1">
<div class="form-group input-group">
<input name="p2" class="form-control" value="param2" type="text" />
<input name="p3" class="form-control" value="param3" type="text" />
<input name="文件名不重要" class="form-control" type="file" accept="image/png, image/jpeg(这里要写上传的文件的类型)" />
<span class="input-group-btn">
<button class="btn btn-default" type="submit">
<span class="glyphicon glyphicon-search"></span>上传
</button>
</span>
</div>
</form>
微信小程序提交参数(JavaScript):
wx.chooseImage({
success (res) {
const tempFilePaths = res.tempFilePaths
wx.uploadFile({
url: 'http://xxx/api/XX?p1=param1',
filePath: tempFilePaths[0],
name: '文件名',
formData: {
'p2': 'param2',
'p3': 'param3'
},
success (res){
console.log(res);
}
})
}
})
这种方式的注意点:
这就是传统的mvc的页面提交方式,是带文件的提交方式,这里要注意的就是,c#部分我贴的代码其实不是http请求,而是socket连接,也就是说,他不限制平台,比如一个单片机,接上一个能够联网且创建socket的模块,不需要实现http协议,就可以直接将数据发送给服务器,然后收到服务器的回复!市场上常用的nbiot模块或者以太网模块或者wifi模块,只要能连接服务器并且创建socket连接,就可以,我当初就是拿这套代码改成c语言版本后跑在单片机上,通过bc35模块连接云服务器的。
第三种:
接收参数:
public struct SomeData{//struct的名称其实不重要
public string p2{get;set;}//注意,get;set;这种属性很重要,如果不是属性很可能参数一直为null!
public int p3{get;set;}
}
[httppost]
public string Get(string p1,[frombody]SomeData sd){//这里的参数名不重要
return p1+sd.p2+sd.p3;//所有的混合参数
}
c#发送参数:
//代码中使用到了Newtonsoft.Json包,请自行下载安装
public string PostData(string url, object o)
{
try
{
var dts = Newtonsoft.Json.JsonConvert.SerializeObject(o);//先将object转为json字符串
var data = Encoding.UTF8.GetBytes(dts);//再将字符串转换为byte[]
var hr= (HttpWebRequest)WebRequest.Create(url);
hr.Method = "POST";
hr.ContentType = "application/json";
hr.ContentLength = data.Length;
using (var rs = hr.GetRequestStream()) rs.Write(data, 0, data.Length);
using (WebResponse hp = hr.GetResponse())
using (Stream s = hp.GetResponseStream())
{
var res = new StreamReader(s).ReadToEnd();
return res;
}
}
catch (Exception)
{
return null;
}
}
//使用:
var result = PostData("http://XXX/api/XX?p1=param1",new { p2 = "param2", p3 = 333 });
ajax提交参数:
var url = "http://XXX/api/XX?p1=param1"
var pms = {
p2 : "p2",
P3 : 333,
}
$.post(url, pms, function(res){
alert(res);
});
微信小程序提交参数(JavaScript):
var pms = {
p2 : "param2",
p3 : 333,
}
wx.request({
url: 'http://XXX/api/XX?p1=param1',
method: 'POST',
header: {'content-type': 'application/json;charset=UTF-8'},
data: pms,
success(re){
console.log(re);
}
});
这种方式的注意点:
这种方式就是现在很流行的json数据通讯方式,这种方式下,微信小程序,ajax等都支持,且代码简洁,比较常用,但是也要注意,就是struct中的内容最好都是get;set;的属性,我之前用变量的方式好像也能收到参数,但是后来又发现不能收到参数,也可能是不同的.net版本导致的,服务器端需要安装Newtonsoft.Json包,一般都会自带有一个旧版本的包,最好还是更新一下。c#传递参数时就必须要用到Newtonsoft.Json包的,如果是wpf项目是不会自带这个包的。安装这个包也很简单,就是到nuget包管理器中搜索然后安装就行了。
各种服务器返回数据后本地解析数据的示例
第一种:
服务器返回:
public string Get(string p1){//返回值就是普通的常用的类型,比如string,int,long,double,等等
return p1;
}
c#解析数据:
var req= (HttpWebRequest)WebRequest.Create("http://xxx/api/xx?p1=1");
var res= (HttpWebResponse)req.GetResponse();
var result = int.TryParse(res, out var v) ? v : default;//非string就用指定的类型TryParse,如果是string,注意了,其中会包含两个双引号,所以结果应该需要replace比如:
var result = res.Trim('\"');//res.Replace("\"",string.Empty);
微信小程序/ajax解析数据:
wx.request({
url: 'http://XXX/api/XX?p1=param1',
success(re){
console.log(re.data);//re基本都是字符串类型,所以直接可以用来判断,如果服务器返回的是string类型,则注意re.data中会有两个双引号一前一后,需要去除掉
}
});
这种方式的注意点:
这种方式对微信ajax等平台不友好,数据返回比较单一,且都是字符串,需要自己去解析内容,比较不方便,虽然服务器返回数据方便,但是对数据的使用者来说造成了麻烦。
第二种:
服务器返回:
public IHttpActionResult Get(string p1){//学过mvc的应该很眼熟吧,没错,就是和mvc的返回方式是一样的!
return Json(new { dt1 = "data1", dt2 = 2345 });//这是返回的是纯json,可以返回任意的对象,json中包括了对象的所有可读的属性。当然,你也可以返回数组,字典,List,struct等等你想返回的东西
var fp = HttpContent.Current.Server.MapPath("~/file/p1.jpg");
return File(fp,MimeMapping.GetMimeMapping(fp),"当我们点击下载时显示的名称.jpg");//这是返回任意的文件,其他更多的方式可参考mvccontroler
}
c#解析数据:
//服务器返回文件时可以直接下载就可以了:
var result = new WebClient().DownloadFile ("http://xxx/api/xx?p1=","指定一个本地的保存文件的地址");
//如果服务器返回的是一个对象,数组,struct,List等时:
public struct SomeData{
public string dt1{get;set;}
public int dt2{get;set;}
}
var hr= (HttpWebRequest)WebRequest.Create("http://xxx/api/xx?p1=1");
var hp = hr.GetResponse();
var s = hp.GetResponseStream();
var res = new StreamReader(s).ReadToEnd();
try{ return Newtonsoft.Json.JsonConvert.DeserializeObject<SomeData>(res); }
catch { return default; }//返回值就是一个struct,当然,上面的SomeData可以是其他的类型,如果json反序列化失败则会抛出异常,然后返回default,返回一个缺省的值。
微信小程序/ajax解析数据:
//如果是文件:
wx.downloadFile({//(摘自微信公众平台:https://developers.weixin.qq.com/miniprogram/dev/api/network/download/wx.downloadFile.html)
url: 'http://xxx/api/xx?p1=', //仅为示例,并非真实的资源
success (res) {
// 只要服务器有响应数据,就会把响应内容写入文件并进入 success 回调,业务需要自行判断是否下载到了想要的内容
if (res.statusCode === 200) {
wx.playVoice({
filePath: res.tempFilePath
})
}
}
})
//如果返回的是纯json内容:
wx.request({
url: 'http://XXX/api/XX?p1=param1',
success(re){
console.log(re.data);
if(re.data.dt1) console.log(re.data.dt1);//可以直接访问属性的,不需要做其他的事情,因为返回的纯json是已经解析后的数据,如果是数组或者list,可以直接each,非常方便
if(re.data.dt2) console.log(re.data.dt2);
}
});
这种方式的注意点:
这种方式对ajax,微信等非常友好,兼容性很好,可以直接互相传递对象,容器数组等等,都是标准的文件或者json对象,也是主流的趋势,兼容多种平台。所以推荐使用。
估计有了这两种方法基本满足了。
一些简单的Post方式WebApi接收参数和传递参数的方法及总结的更多相关文章
- JavaWeb_(Struts2框架)参数传递之接收参数与传递参数
此系列博文基于同一个项目已上传至github 传送门 JavaWeb_(Struts2框架)Struts创建Action的三种方式 传送门 JavaWeb_(Struts2框架)struts.xml核 ...
- Android通过DeepLink方式跳转其他App传递参数
网上对于安卓DeepLink方式跳转传递参数的例子较少,说的也不客观,实践之后发现还是有一些坑.其实为什么要用DeepLink方式跳转,有些是因为引流的原因,他们希望通过网页就能直接跳转到App的界面 ...
- SpringMVC入门(二)—— 参数的传递、Controller方法返回值、json数据交互、异常处理、图片上传、拦截器
一.参数的传递 1.简单的参数传递 /* @RequestParam用法:入参名字与方法名参数名不一致时使用{ * value:传入的参数名,required:是否必填,defaultValue:默认 ...
- 17_Android中Broadcast详解(有序广播,无序广播)最终广播,Bundle传递参数,传递参数的时候指定权限
1 Broadcast是Android中的四大组件之一,他的用途很大,比如系统的一些广播:电量低.开机.锁屏等一些操作都会发送一个广播. 2 广播被分为两种不同的类型:"普通广播( ...
- python 函数参数的传递(参数带星号的说明) 元组传递 字典传递
python中函数参数的传递是通过赋值来传递的.函数参数的使用又有俩个方面值得注意:1.函数参数是如何定义的 2.在调用函数的过程中参数是如何被解析 先看第一个问题,在python中函数参数的定义主要 ...
- python 函数参数的传递(参数带星号的说明)
python中函数参数的传递是通过赋值来传递的.函数参数的使用又有俩个方面值得注意:1.函数参数是如何定义的 2.在调用函数的过程中参数是如何被解析 先看第一个问题,在python中函数参数的定义主要 ...
- SpringMVC中,前台jsp封装参数,绑定参数,传递参数到后台controller的过程详解
前台到后台的流程:前台jsp->后台:controller控制器层->service业务层->DAO数据访问层->数据库model模型层. 从上面流程可知,前台jsp的数据,想 ...
- Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数
上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...
- ashx接收参数 ashx传递参数
原文发布时间为:2009-09-30 -- 来源于本人的百度文章 [由搬家工具导入] Handler.ashx文件: <%@ WebHandler Language="C#" ...
- [python] 带有参数并且传递参数的装饰器
场景时这样的,我有个一大堆任务,我要给这些任务计时,入库.就需要一个带有参数的装饰器来记录任务名称, 在任务执行前和执行之后都需要记录任务当时执行的时刻. #-*- encoding=utf-8 -* ...
随机推荐
- 18 JavaScript中的三元运算
18 JavaScript中的三元运算 先来看一个例子: let a = 10; let b = 20; let d = a > b? a: b console.log(d); // 20 三元 ...
- #trie,树链剖分#洛谷 6088 [JSOI2015]字符串树
题目 分析 显然树上的问题可以转换成根节点到两点的答案减去2倍根节点到LCA的答案 化边为点,考虑子节点承接父节点的trie,再加入一条新的字符串, 在循环的过程中统计一个位置被多少个字符串经过, 这 ...
- C 语言中的 switch 语句和 while 循环详解
C 语言中的 switch 语句 替代多重 if..else 语句,可以使用 switch 语句.switch 语句用于选择多个代码块中的一个来执行 switch(表达式) { case x: // ...
- 直播预告丨Hello HarmonyOS进阶课程第三课——游戏开发实践
为了帮助初识HarmonyOS的开发者快速入门,我们曾推出Hello HarmonyOS系列一共5期课程,从最基础的配置IDE和创建Hello World开始,详细介绍HarmonyOS基础.开发环境 ...
- How Python Handles Big Files
The Python programming language has become more and more popular in handling data analysis and proc ...
- 重新点亮shell————周期性脚本[八]
前言 简单介绍一下周期性脚本 正文 周期性脚本之前先介绍一下信号. 捕获信号脚本的编写: kill 默认会发送15号信号给应用程序 ctrl+c 发送2号信号给应用程序 9号信号不可阻塞信号 所以只有 ...
- mysql 在c# EF 中无法生成对象
正文 1. 创建个vs2013项目,导入EntityFramework.dll. MySql.Data.dll. MySql.Data.Entity.EF6.dll 2. 工具 -> 扩展和更新 ...
- node excel采集数据
前言 个人写过无数的脚本,但是一直没有整理,后续整理脚本. 需求: 生成一堆激活码. 业务: 需要拿到一个token, 然后调用某个api获取激活码. 正文 思路: 1.http请求 axios 2. ...
- Chat2table,简易表格分析助手
一 写在前面 之前用智谱AI的Chatglm3-6b模型写过一个简单的论文阅读助手,可用来辅助论文阅读等.而像表格,如Excel.CSV文件等内容的分析,也是不可忽略的需要,因此本文同样使用Chatg ...
- [Violation] 'click' handler took 429ms
问题 violation 意思为侵权,违背,违反,也就是说明click函数执行违反了某些规则 原因测试 当click事件中执行的程序耗时过长,超过160ms左右的时候就会显示该信息,测试最低155ms ...