前言

即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录。

接口描述

首先说明一下,基于Http协议的Get、Post请求,网上有很多例子,其实方法都是一样的,这块没什么好说的,我也测试过我的代码,正常的调用是没问题的。问题不是在请求方法上,而是在如何取出数据上。
因为对应我需求接口的开发是个实习生,对于如何提供接口,他并不熟悉,其中我还帮了一些忙,但我毕竟不是很熟BS端那块,纠结了1天多才调通接口。
描述一下需求接口:
OA方需要提供头像下载的接口供即时通信初次登陆时下载头像。
思路如下:
1.接口内将OA头像文件夹打包压缩成zip文件
2.将zip文件,转成字节流byte[]
3.将字节流byte[]序列化成json格式 返回

问题

思路1、2他按照我的要求做了,我测试接口后遇到的问题是取出的byte[]顺序不对,我本地反序列化后转成zip文件没法解压,多次测试后我又让他按照思路3来做。

测试接口,遇到了个问题,我反序列化出来的json字符串,包含了d,如下:

解决

因为不熟悉这块,我不知道如何取出d中的数据,上网查也不好查,因为几乎没有问这块的,后来我问OA做手机端的同事,才知道他们提供的接口方法都是void,不在返回值的,都是通过http的Context.Response返回的,在调用的时候不会出现这个d字符。然而他也不知道如何取出d中的数据,没办法只能在网上再找,后来在一篇CSDN的博客中的评论里找到了办法,将json转换成hash表的格式,然后直接取出来d的数据,然后反序列化json成对象,如下:

string headjson = WebAPIHelper.HttpPost(OAAddress, null);
JavaScriptSerializer json = new JavaScriptSerializer();
Hashtable table = (Hashtable)json.Deserialize(headjson, typeof(Hashtable));
string d = table["d"].ToString();//取出d中的数据
HeadByte h1 = JsonConvert.DeserializeObject<HeadByte>(d);

到此为止,问题终于解决。

拓展

因为比较在意普通的接口是如何提供返回结果的,我特意看一下OA中的WebAPI方法,同事说过,不带d的方法无需返回值,使用void即可,请求返回的结果都在Response中,json字符串出现d的原因是方法的返回值是string类型,特附上不需要另外取json中d的方法:

         [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
[WebMethod(Description = " 获取筛选条件", EnableSession = true)]
public void GetTestList(string Type,string UserID)
{
Context.Response.ContentType = "text/plain";
Context.Response.Charset = "UTF-8";
Context.Response.ContentEncoding = System.Text.Encoding.UTF8;
Dictionary<string, object> dicReturn = new Dictionary<string, object>();
Dictionary<string, object> dic = new Dictionary<string, object>();
string jsonStr = string.Empty;//保存返回的json字符串
try
{
//将返回的结果放到dic中
//可以放到list里也可以放到DataTable中
List<SortModel> list = xxx.GetXXXXXList(parames1, parames2);
dic.Add("Count", xxx.GetXXXXXCount(parames1, parames2));
dic.Add("List", list);
//或者
DataTable dt = xxx.GetXXXXX(parames1, parames2);
dic.Add("Count", xxx.GetXXXXXCount(parames1, parames2);
dic.Add("List2", dt);
//获取成功
dicReturn.Add("State", "");
dicReturn.Add("ErrorMsg", "获取成功");
dicReturn.Add("Data", dic);
dicReturn.Add("ErrCode", "");
}
catch (Exception ex)
{
dicReturn.Add("State", "");
dicReturn.Add("ErrorMsg", ex.Message);
dicReturn.Add("Data", "");
dicReturn.Add("ErrCode", "");
}
//序列化 json字符串
jsonStr = JsonConvert.SerializeObject(dicReturn);
Context.Response.Write(jsonStr);
Context.Response.End(); }

附上post请求的方法:

 /// <summary>
/// 同步Post
/// </summary>
/// <param name="Url"></param>
/// <param name="postDataStr"></param>
/// <returns>返回json格式</returns>
public static string HttpPost(string Url, IDictionary<string, string> Params)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.Method = "POST";
//request.ContentType = "application/x-www-form-urlencoded";
request.ContentType = "application/json";
request.CookieContainer = cookie; //发送POST数据
StringBuilder bufferParams = new StringBuilder();
if (!(Params == null || Params.Count == ))
{
int i = ;
foreach (string key in Params.Keys)
{
if (i > )
{
bufferParams.AppendFormat("&{0}={1}", key, Params[key]);
}
else
{
bufferParams.AppendFormat("{0}={1}", key, Params[key]);
i++;
}
}
}
request.ContentLength = Encoding.UTF8.GetByteCount(bufferParams.ToString()); Stream myRequestStream = request.GetRequestStream();
StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312"));
myStreamWriter.Write(bufferParams);
myStreamWriter.Close(); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); response.Cookies = cookie.GetCookies(response.ResponseUri);
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
string retString = myStreamReader.ReadToEnd();
#region ContentType = "application/x-www-form-urlencoded"处理方式
//服务器端返回的是一个XML格式的字符串,XML的Content才是我们所需要的数据
//XmlTextReader Reader = new XmlTextReader(myResponseStream);
//Reader.MoveToContent();
//string retString = Reader.ReadInnerXml();//取出Content中的数据
//Reader.Close();
#endregion
myStreamReader.Close();
myResponseStream.Close(); return retString;
}

总结

对于WebAPI调用,在BS端中,实在是很小白的东西,但是再怎么小白,没做过还是会花一些时间的。2019年,希望自己可以成长的更快,变得更优秀。

WebAPI调用笔记的更多相关文章

  1. WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)

    WebAPI调用笔记   前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...

  2. Asp.Net Core WebApi学习笔记(四)-- Middleware

    Asp.Net Core WebApi学习笔记(四)-- Middleware 本文记录了Asp.Net管道模型和Asp.Net Core的Middleware模型的对比,并在上一篇的基础上增加Mid ...

  3. 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换

    路由其实也可以很简单-------Asp.net WebAPI学习笔记(一)   MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中, ...

  4. 输出的数据格式是如何决定的-------Asp.net WebAPI学习笔记(二)

    在上一篇文章<路由其实也可以很简单>,我们解决了路由问题,这篇文章,我们来研究剩下的另一个问题,为何我们的方法返回的是一个列表,输出到客户端的时候,变成json呢,大家应该还记得我们上一篇 ...

  5. 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一)

    MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中,一切皆路由,url中是完全拒绝"?"和“&”.对此,我 ...

  6. WebAPI学习笔记

    WebAPI WebApi是添加到Asp.Net平台的一个新特性,可以快速的创建Web服务,并对客户端提供HTTP的API调用接口 WebApi是建立在MVC框架基础之上,但不属于MVC的一部分. 序 ...

  7. keras模块学习之-参数初始化与对象调用-笔记

    本笔记由博客园-圆柱模板 博主整理笔记发布,转载需注明,谢谢合作! 参数初始化(Initializations) 这个模块的作用是在添加layer时调用init进行这一层的权重初始化,有两种初始化方法 ...

  8. MySql存储过程的创建与使用及在thinkphp中如何调用笔记

    学习sql的存储过程,笔记总结如下: MySQL默认将分号,即";"作为语句的分隔符.如果是这样的话,则一个存储过程将很难正常创建,因为它的BEGIN和END之间可以是任意数量的S ...

  9. 关于webapi调用wcf并发假死的分析

    原来IDFA(IOS推广获取到用户IOS手机的唯一标识,如果不刷机的话跟安卓的IMEI一样)在公司正常的页面是公用用一个网站和数据库的. 起初怀疑并发数太多,把数据库连接池的数量从一百设置到三百,确实 ...

随机推荐

  1. Sketchup (待续)

    Sketchup插件 来自20个最好用的SketchUp插件 https://www.bilibili.com/video/av17242031/?from=search&seid=15336 ...

  2. FineUI 相关

    FineUI 相关(ExtAsp.Net 2008-2017),记在这把,免得找不到了. 不知道同年代的类似项目Coolite怎么样了?更名为Ext.net了,在国外活得还算滋润,在国内嘛..死贵死贵 ...

  3. [20180603]Python读写csv

    原文:https://docs.python.org/3/library/csv.html 进入python官网后,选择document,然后选择library reference. 读取: impo ...

  4. python中split()的用法

    Python split() 通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则仅分隔 num 个子字符串. 语法: str.split(str="", num=str ...

  5. 在 Azure 上部署 Kubernetes 集群

    在实验.演示的时候,或者是生产过程中,我经常会需要运行一些 Docker 负载.虽然这在本地计算机上十分容易,但是当你要在云端运行的时候就有点困难了.相比于本地运行,在云端运行真的太复杂了.我尝试了几 ...

  6. 操作redis

    数据库分为: 1)传统的关系型数据库 mysql.oracle.sql server.sqllie.db2 id name passwd cratetime stu 特点: a 数据存在磁盘上 b 使 ...

  7. ACTIVEMQ 实例化到MSSQL

    实例化文章很多,不重复,自行查询 直接上XML <!-- Licensed to the Apache Software Foundation (ASF) under one or more c ...

  8. msgid 属性

    Android源码中的String.xml文件,msgid这个属性是干嘛的? 全局资源,方便引用.比如在布局的text和activity中用到.

  9. Linux驱动

    1 驱动分类 常规分类:字符设备.块设备.网络设备 字符设备:一种按字节来访问的设备,字符驱动负责驱动字符设备,这样的驱动通常实现open.close.read和write系统调用.如串口.LED.按 ...

  10. android开发_view和view属性

    一.view视图的宽度和高度属性,属性值:固定和浮动两种状态 1属性为固定值 <View android:layout_width="30dp" android:layout ...