用.net访问电子枢纽信用中心的数据查询服务
概要说明
电子枢纽全称国家交通运输物流公共信息平台,主要提供物流及生产企业进行物流相关数据交换的标准和API,详细介绍可参考其官网www.logink.org,本文假定阅读者对该平台已有了解,并已成功申请了相应的帐号和数据交换服务。
信用中心是电子枢纽众多数据服务中的一个,提供物流参与者信用信息的上传和查询,包括运输车辆、从业人员等。官方的示例和介绍大多以Java为主,.net的非常少,希望本文可以帮助.net开发人员快速掌握数据交换方式。
电子枢纽的数据服务分为两种,一种称为数据交换,另一种称为服务调用。
数据交换是一种类似电子邮件的行为,可以把电子枢纽看作是一个邮件服务器,发送和接收数据就与收发电子邮件的方式类同。
服务调用就是常规的HTTP请求,主要用于向电子枢纽查询信息,例如对于信用中心来说,可以查询到车辆的运政信息、诚信记录等。
本文主要介绍的是服务调用方式,要调用电子枢纽提供的服务,首先必须确保已经开通了相关服务,开通后还需要获得服务的ID,这些任务都可以从电子枢纽的用户管理中心完成。
在调用服务前,必须获得用户验证的令牌(Access Token),这项工作可通过统一认证服务完成,获得令牌后,方可凭令牌调用相关服务。
引入服务
电子枢纽的数据接口都是以Web Service提供的,所以在开始编码之前,可以先引入相关的服务,在VS里直接添加服务引用即可,相关的服务地址可以在官网的开放接入中心找到。
值得注意的是,虽然电子枢纽提供的大部分Web Service都可以在VS中直接引入,但还有个别不能采用这种“添加服务引用”的方式,目前已知的就是信用中心服务。对于这种情况,需要在VS中以Web引用的方式来添加,具体方法如下。
右键点击解决方案浏览器中项目或引用(Reference)的节点,在菜单中选择“添加服务引用”(Add Service Reference),在弹出的对话框里点击“高级”(Advanced),再在弹出的服务引用设置对话框里点击“添加Web引用”(Add Web Reference)即可调出添加Web引用的对话框。
至于为什么要这样,由于我对SOAP和WCF没有太多了解,实在没法回答这个问题,希望这方面的大神可以给出解答。
访问代码
引用添加完以后,VS会为我们自动生成好相应的类型,直接使用就可以。
首先是获取令牌,统一验证服务的客户端类型是AuthenServiceClient,实例化以后调用他的authenticate方法,方法签名如下:
authenticate(string applicant, string userid, string password, string resource)
关于这个方法的具体说明,可参考官方说明。
返回值的tokenValid属性指示是否验证成功,如果为true,可通过token属性获取令牌的值。示例代码如下:
private bool Authenticate(LoginkUser user, string resId, out string token)
{
AuthenServiceClient clnt = new AuthenServiceClient(); var result = clnt.authenticate(user.ExchangeCode, user.ExchangeCode, user.Password, resId); if (result.tokenValied)
token = result.token;
else
token = null; clnt.Close(); return token != null;
}
得到令牌以后,就可以直接调用信用中心的查询服务了,VS生成的信用中心服务的客户端类型为LoginkServiceService,实例化后调用它的InterfaceName方法。
genericResult InterfaceName(authentication Authentication, publicInformation PublicInformation, string BusinessInformation)
这个方法没有找到官方的文档,由于各个参数比较复杂,就不一一介绍了(其实我自己也没搞明白),直接照抄下面的示例就可以了。
private string CallCreditService(LoginkUser user, string token, string action, string request)
{
var css = _settings.CreditService; Logink.Services.Credit.security security = new Logink.Services.Credit.security();
security.LogisticsExchangeCode = user.ExchangeCode;
security.UserTokenID = token; Logink.Services.Credit.authentication authentication = new Logink.Services.Credit.authentication();
authentication.UserName = user.ExchangeCode;
authentication.UserPassword = user.Password;
authentication.ServiceId = css.ResourceId;
authentication.UserId = user.ExchangeCode; Logink.Services.Credit.publicInformation publicInformation = new Logink.Services.Credit.publicInformation();
publicInformation.ServiceType = "";
publicInformation.ActionType = action; Logink.Services.Credit.LoginkServiceService service = new Logink.Services.Credit.LoginkServiceService();
service.Url = css.Url;
service.Security = security; var result = service.InterfaceName(authentication, publicInformation, request); if (result.ResultCode)
{
return result.BusinessInformation;
}
else
throw new ExchangeException(result.ExceptionInformationCode, result.ExceptionInformation);
}
示例中这个CallCreditService方法已经封装了调用信用中心服务的各种参数,其中action参数表示业务类型,官网有介绍,下面再详细说下request参数。
request参数实际上是个经过Base64编码的XML字符串,XML的内容就是各个传入参数的值,需要注意的是,传入的这个XML串并不是完整的文档,而是根节点以下的内容,千万不要把根节点也传上来,如果你使用XmlDocument来处理传入参数,可以使用根节点的InnerXml属性。
Base64编码相对来说就比较简单了,System.Convert类型直接支持转换为Base64,默认情况下电子枢纽使用的是UTF8编码,在编/解码时不要搞错,否则会查不到数据或出现乱码。
private string XmlToBase64(string xml)
{
if (string.IsNullOrEmpty(xml))
return xml; return Convert.ToBase64String(Encoding.Utf8.GetBytes(xml));
}
最后,需要处理的是InterfaceName的返回值,返回值的ResultCode指示是否调用成功,如果不成功可通过ExceptionInformationCode属性获取错误代码,否则可以通过BusinessInformation属性获取返回的文本。
返回的文本同样是一个Base64编码的XML字符串,转换成明文以后就可以直接使用了,不过对于明文的处理是一件比较头痛的事,经过多次试验最终摸索出以下的规律。
文本为空串:可能是没有查询到相关的内容。
文本不是XML:尽管ResultCode为true,但仍旧可能是出现了错误,文本的内容就是出错信息。
对于这些情况,我们的程序都应该进行相应的处理。
public XmlDocument QueryCredit(QueryParameters parameters)
{
if (parameters == null)
throw new ArgumentNullException(nameof(parameters)); AccessToken token;
string data;
bool forceRenewToken = false; retry: // 通过统一验证服务获取用户的访问令牌
token = GetToken(_user, _settings.CreditService.ResourceId, forceRenewToken); // 将传入参数序列化为XML
data = parameters.GetXml();
// 对XML转换为BASE64编码
data = XmlToBase64(data); try
{
// 调用信用中心的Web Service
data = CallCreditService(_user, token.Value, parameters.ActionName, data);
}
catch(ExchangeException ee)
{
// 判断是否需要更新令牌
if (ee.IsTokenInvalid && !forceRenewToken)
{
forceRenewToken = true;
goto retry;
}
else
throw;
} if (!string.IsNullOrEmpty(data))
{
// 返回的内容已做了BASE64编码处理,将它转换为XML。
data = Base64ToXml(data); // 部分情况下平台返回的可能是一串错误信息而非XML,因此对不是"<"开头的直接按错误信息处理。
if (data[] == '<')
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(data); return doc;
}
else
throw new ExchangeException(data);
}
else
{
// 如果返回的内容为空,可能是没有查到相关数据。
throw new ExchangeException("", "暂时没有查到相应数据");
} }
到些为止,调用信用中心服务所需的代码都已经大致做了介绍,把它们串起来以后就形成了一个完整的程序,全部源代码请点击此处。由于我的电脑上装的是VS2015,低版本的VS可能没办法打开,实在抱歉。
相关资源
几个必须加入的QQ群
213604083:平台接入群,这是必加的一个群,有很多平台的管理人员在里面,一些基础的问题可以问问他们,当然还有一点很重要的是群里有开发所需要的许多资源。
383412768:信用接入群,如果要使用信用中心服务,这就是你要找的组织。
363016382:园区通接入群,如果你是为了接入而接入(你懂的),那这里是也是必须的。
601484722:充装数据接入群。
用.net访问电子枢纽信用中心的数据查询服务的更多相关文章
- linux下配置zookeeper注册中心及运行dubbo服务
dubbo和zookeeper的关系 简单来说打个比方:dubbo就是动物园的动物,zookeeper是动物园.如果游客想看动物的话那么就去动物园看.比如你要看老虎,那么动物园有你才能看到.换句话说我 ...
- 《springcloud 一》搭建注册中心,服务提供者,服务消费者
注册中心环境搭建 Maven依赖信息 <parent> <groupId>org.springframework.boot</groupId> <artifa ...
- 使用Redis为注册中心的Dubbo微服务架构(基于SpringBoot)
title: 使用Redis为注册中心的Dubbo微服务架构(基于SpringBoot) date: 2019-07-30 14:06:29 categories: 架构 author: mrzhou ...
- Java开源协同办公项目:数据中心,自定义查询语句使用教程
O2OA提供的数据管理中心,可以让用户通过配置的形式完成对数据的汇总,统计和数据分组展现,查询和搜索数据形成列表数据展现.也支持用户配置独立的数据表来适应特殊的业务的数据存储需求.本文主要介绍如何在O ...
- ECharts访问后台,JSON格式返回数据实例
完成图 一.页面代码 <%@ page language="java" contentType="text/html; charset=UTF-8" pa ...
- matlab学习笔记12_2创建结构体数组,访问标量结构体,访问非标量结构体数组的属性,访问嵌套结构体中的数据,访问非标量结构体数组中多个元素的字段
一起来学matlab-matlab学习笔记12 12_2 结构体 创建结构体数组,访问标量结构体,访问非标量结构体数组的属性,访问嵌套结构体中的数据,访问非标量结构体数组中多个元素的字段 觉得有用的话 ...
- Ant Design框架中不同的组件访问不同的models中的数据
Ant Design框架中不同的组件访问不同的models中的数据 本文记录了我在使用该框架的时候踩过的坑,方便以后查阅. 一.models绑定 在某个组件(控件或是页面),要想从某个models中获 ...
- 历史上最详细的SpringCloud搭建微服务的过程。(包括注册中心,服务提供者和服务消费者)
首先搭建注册中心,创建一个springboot的maven工程. 工程创建完成之后,先在资源文件中的application.properties中写配置文件. server.port= spring. ...
- T-SQL - 访问远程数据库并对其数据表进行操作
一.概述 很多时候我们需要在.NET应用程序中使用一条SQL语句来访问来自不同服务器.不同数据库中的不同的表,实现方法有很多.我们可以在.NET应用程序中建立数据访问层,使用ADO.NET Entit ...
随机推荐
- 将jquery.shCircleLoader插件修改为zepto.js兼容
经过查阅资料zepto 和 jquery 的区别后发现是 (1)zepto.js 删去了 jquery 的 innerHeight() 和 innerWidth() 属性 (2)zepto.js和 ...
- More Effective c++
指针和引用 引用对象必须存在,即不能引用空值,指针可以指向空值,引用必须初始化指向一个对象 指针可以改变指向的对象,引用不能改变所引用的对象 不改变指向对象使用引用,改变指向对象使用指针 重载[]时必 ...
- autolayout
autolayout.因为之前都是用frame,用代码来做,并且在布局时也很少用storyboard和xib.使得我再这方便经验很欠缺,想用,但是又怕用不好,出现各种意想不到的bug.但是又忽然想到, ...
- Python自动化 【第十二篇】:Python进阶-MySQL和ORM
本节内容 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令 创建数据库 外键 增删改查表 权限 事务 索引 python 操作mysql ORM sql ...
- highcharts 柱状图 动态加载
highcharts柱状图动态加载 (1):导入样式 <script type="text/javascript" src="<%=request.getCo ...
- 转向Web
一直搞桌面软件开发,用C++绘界面那蛋疼的日子是记忆犹新,也不想钻研什么网络协议了,好好搞Web方面吧,它的开放很让人激动 Python是个好东西,适合许多场合,包括云计算,科学计算,软件测试,运维等 ...
- Samba安装配置
Samba简介 Samba官网:http://www.samba.orgSMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和打印机的一种通信协议,它为局域网内的不 ...
- Net分布式系统之三:Keepalived+LVS+Nginx负载均衡之高可用
上一篇写了nginx负载均衡,此篇实现高可用(HA).系统整体设计是采用Nginx做负载均衡,若出现Nginx单机故障,则导致整个系统无法正常运行.针对系统架构设计的高可用要求,我们需要解决Nginx ...
- python爬虫——黑板客老师课程学习
程序: 目标url 内容提取 表现形式 为什么: 大数据——数据膨胀,信息太多了,不知道哪些信息适合你,例如谷歌搜索引擎. 垂直行业搜索——某一个行业的搜索,与搜索引擎最大的区别:搜索引擎是告诉你哪些 ...
- 使用FreePic2Pdf导出书签至Word建立层级目录——快速初始化Word笔记本目录
使用FreePic2Pdf导出书签至Word建立层级目录 --快速初始化Word笔记本目录 文:安徽师范大学2014级计算机科学与技术 王昊 (Get Contact:441301158@qq.com ...