一些简单的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 -* ...
随机推荐
- #dp#C 公共子序列
题目 给定两个字符串\(s1,s2\),求它们的\(LCS\) 满足\(|s1|\leq 10^6,|s2|\leq 10^3\) 分析 考场写了\(O(|s1|*|s2|)\)成功TLE, 考虑突破 ...
- vue3中router配置中的children怎么用
在Vue 3中,当你使用Vue Router创建路由配置时, children属性允许你为某个路由定义嵌套路由.这意味着你可以在父路由下设置子路由,从而构建出具有层级结构的URL路径. 这里是一个基本 ...
- 共筑使能千行百业的数字底座 | HDC 2022松湖对话顺利召开
11月5日,华为开发者大会2022松湖对话在东莞松山湖凯悦酒店召开,开放原子开源基金会秘书长冯冠霖.华为终端BG软件部总裁龚体.深圳国家金融科技测评中心董事长钟剑.鸿湖万联(江苏)科技发展有限公司董 ...
- C++ 智能指针和内存管理:使用指南和技巧
C++是一门强大的编程语言,但是在内存管理方面却存在着一些问题.手动管理内存不仅费时费力,而且容易出错.因此,C++中引入了智能指针这一概念,以更好地管理内存. 什么是智能指针? 在C++中,内存的分 ...
- 从模型到部署,教你如何用Python构建机器学习API服务
本文分享自华为云社区<Python构建机器学习API服务从模型到部署的完整指南>,作者: 柠檬味拥抱. 在当今数据驱动的世界中,机器学习模型在解决各种问题中扮演着重要角色.然而,将这些模型 ...
- C#.Net WinForm学习笔记
.Net WinForm学习笔记 1,MDI窗体设有两个窗体frmMain,frmChild,则:frmMain: 设IsMdiContainer属性为true 打开子窗口: 在相关事件中写如下代 ...
- SpringCloud OpenFeign token中转
OpenFeign 的本质是调用指定服务的 Controller. 前后端分离项目,调用 Controller 是需要传递 token 的. OpenFeign 并不会自动携带 token 去访问 C ...
- vue element序号翻页连续排序
type="index" :index="indexMethod" // 序号翻页连续排序 indexMethod(index) { return (this. ...
- openGauss基于4路鲲鹏服务器的性能调优
1.概述 本文主要描述了在4路鲲鹏服务器上,通过软硬件协同优化配置达到openGauss数据库的极致性能的方法. 主要包括软硬件要求.BIOS配置.网卡配置.磁盘配置.服务器参数设置.数据库参数配置. ...
- HarmonyOS NEXT调优工具Smart Perf Host高效使用指南
在软件开发的过程中,很多开发者都经常会遇到一些性能问题,比如应用启动慢.点击滑动卡顿.应用后台被杀等,想要解决这些问题势必需要收集大量系统数据.而在收集数据的过程中,开发者则需要在各种工具和命令之 ...