引子

最近根据业务的一些需求,所以放弃从快递鸟对接去电子面单,转而直接对接韵达开发平台:http://open.yundasys.com/ ,中间踩了一些坑,借此做了一个小案例给大伙,瞅瞅,若有需改进之处,还请指出!!!

废话不多数:首先咱先对韵达的一些接口参数了解清楚:

当然附上地址:http://open.yundasys.com/index.php?g=&m=ApiTools&a=exm

还有接口的一些SDK文件地址,这个就各位观众大老爷们自己去看了:http://open.yundasys.com/index.php?g=&m=ApiTools&a=apps&id=14

解决方案

上代码走起:基础参数的模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication1
{
  //请求参数
class RequestVO
{
/// <summary>
/// XML数据内容
/// </summary>
public string xmldata { get; set; }
/// <summary>
/// 合作社区ID,由韵达给大客户提供
/// </summary>
public string partnerid { get; set; }
/// <summary>
/// 密码
/// </summary>
public string password { get; set; }
/// <summary>
/// 数据请求类型,如request=data;其中data表示下单,详细请见request字典表
/// </summary>
public string request { get; set; }
/// <summary>
/// 请求的版本,当前版本为1.0
/// </summary>
public string version { get; set; }
}
}

  

主体参数模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace ConsoleApplication2
{
/// <summary>
/// 数据体
/// </summary>
public class Orders
{
[XmlElement("order")]
public List<Order> order { get; set; }
} /// <summary>
/// 韵达取号订单信息
/// </summary>
public class Order
{
/// <summary>
/// 订单唯一序列号
/// </summary>
public string order_serial_no { get; set; }
/// <summary>
/// 大客户系统订单的订单号
/// </summary>
public string khddh { get; set; }
/// <summary>
/// 内部参考号,供大客户自己使用,可以是客户的客户编号
/// </summary>
public string nbckh { get; set; }
/// <summary>
/// 单号
/// </summary>
public string mailno { get; set; }
/// <summary>
/// 发件人
/// </summary>
[XmlElement("sender")]
public Sender sender { get; set; }
/// <summary>
/// 收件人
/// </summary>
[XmlElement("receiver")]
public Receiver receiver { get; set; }
/// <summary>
/// 物品重量
/// </summary>
public long weight { get; set; }
/// <summary>
/// 尺寸,格式(长,宽,高),单位cm
/// </summary>
public string size { get; set; }
/// <summary>
/// 货物金额
/// </summary>
public decimal value { get; set; }
/// <summary>
/// 商品集合
/// </summary>
[XmlElement("items")]
public Items items { get; set; }
/// <summary>
/// 订单备注
/// </summary>
public string remark { get; set; }
/// <summary>
/// 可以自定义显示信息1
/// </summary>
public string cus_area1 { get; set; }
/// <summary>
/// 可以自定义显示信息2
/// </summary>
public string cus_area2 { get; set; } }
public class Sender
{
/// <summary>
/// 姓名
/// </summary>
public string name { get; set; }
/// <summary>
/// 公司
/// </summary>
public string company { get; set; }
/// <summary>
/// 严格按照国家行政区划,省市区三级,逗号分隔。示例上海市,上海市,青浦区(cod订单必填)
/// </summary>
public string city { get; set; }
/// <summary>
/// 需要将省市区划信息加上,例如:上海市,上海市,青浦区盈港东路7766号
/// </summary>
public string address { get; set; }
/// <summary>
/// 邮编
/// </summary>
public string postcode { get; set; }
/// <summary>
/// 固定电话
/// </summary>
public string phone { get; set; }
/// <summary>
/// 移动电话固定电话或移动电话至少填一项
/// </summary>
public string mobile { get; set; } public string branch { get; set; }
}
public class Receiver
{
/// <summary>
/// 姓名
/// </summary>
public string name { get; set; }
/// <summary>
/// 公司
/// </summary>
public string company { get; set; }
/// <summary>
/// 严格按照国家行政区划,省市区三级,逗号分隔。示例上海市,上海市,青浦区(cod订单必填)
/// </summary>
public string city { get; set; }
/// <summary>
/// 需要将省市区划信息加上,例如:上海市,上海市,青浦区盈港东路7766号
/// </summary>
public string address { get; set; }
/// <summary>
/// 邮编
/// </summary>
public string postcode { get; set; }
/// <summary>
/// 固定电话
/// </summary>
public string phone { get; set; }
/// <summary>
/// 移动电话固定电话或移动电话至少填一项
/// </summary>
public string mobile { get; set; }
public string branch { get; set; }
}
/// <summary>
/// 明细集合
/// </summary>
public class Items
{
[XmlElement("item")]
public List<Item> item { get; set; }
}
/// <summary>
/// 明细信息
/// </summary>
public class Item
{
/// <summary>
/// 商品名称
/// </summary>
public string name { get; set; }
/// <summary>
/// 商品数量
/// </summary>
public int number { get; set; }
/// <summary>
/// 商品备注
/// </summary>
public string remark { get; set; }
}
}

  

请求方法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO;
using System.Collections.Specialized;
using System.Net; namespace ConsoleApplication1
{
/// <summary>
/// POST提交
/// </summary>
class HttpClient
{
/// <summary>
///
/// </summary>
/// <param name="url"></param>
/// <param name="parameters"></param>
/// <returns></returns>
public static HttpWebResponse post(String url, IDictionary<string, string> parameters)
{
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded"; //如果需要POST数据
if (!(parameters == null || parameters.Count == 0))
{
StringBuilder buffer = new StringBuilder();
int i = 0;
foreach (string key in parameters.Keys)
{
if (i > 0)
{
buffer.AppendFormat("&{0}={1}", key, parameters[key]);
}
else
{
buffer.AppendFormat("{0}={1}", key, parameters[key]);
}
i++;
}
byte[] data = Encoding.UTF8.GetBytes(buffer.ToString());
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
}
return request.GetResponse() as HttpWebResponse;
} /// <summary>
///
/// </summary>
/// <param name="url"></param>
/// <param name="data"></param>
/// <returns></returns>
public static String post(String url, String postdata)
{
try {
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
byte[] data = Encoding.UTF8.GetBytes(postdata.ToString());
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
string outMessage = sr.ReadToEnd();
sr.Close();
return outMessage;
} catch (Exception ex) {
throw ex;
}
} }
}

  

要求

当前按照SDK的要求:

请求报文说明:

1. 数据传输以HTTP POST方式发送,数据字符集一律采用UTF-8

2. xmldata首先需要进行base64编码

3. validation的效验方式采用 MD5(xmldata + partnerid + 密码),这里的加号为字符串连接符号。

4. 所有参数最终均须在完成数据转换后进行URL编码。

请求报文详细解释:

1.假设partnerid为YUNDA;密码为123456;xmldata内容为

<order></order>

2.xmldata经过base64编码以后变成PG9yZGVyPjwvb3JkZXI+

3.那么要签名的内容为PG9yZGVyPjwvb3JkZXI+YUNDA123456,经过md5后的内容就为f197e870a12528e38cb483b4e371f4ea

4.然后再对xmldata经过URL编码,得到字符串PG9yZGVyPjwvb3JkZXI%2B

5.同样需要对其他字段进行URL编码,否则可能会影响POST传递,具体请参见HTTP POST传输协议

6.最终要发送的数据为: partnerid=YUNDA&version=1.0&request=data&xmldata=PG9yZGVyPjwvb3JkZXI%2B&validation=f197e870a12528e38cb483b4e371f4ea

不拉不拉不拉,一大堆,大老爷们自己去看,这些数据转换的方法我直接贴出:

using System;
using System.Text;
using System.Web;
using System.IO;
using System.Xml.Serialization; namespace ConsoleApplication1
{
class DataTransform
{
/// <summary>
/// 组装主体内容
/// </summary>
/// <param name="requestVO"></param>
/// <returns></returns>
public static String signData(RequestVO requestVO)
{
String xmldata = Convert.ToBase64String(System.Text.Encoding.GetEncoding("UTF-8").GetBytes(requestVO.xmldata));
string validation = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(xmldata + requestVO.partnerid + requestVO.password, "MD5").ToLower();
string signdata = "partnerid=" + requestVO.partnerid + "&version=" + requestVO.version + "&request=" + requestVO.request + "&xmldata=" + HttpUtility.UrlEncode(xmldata) + "&validation=" + validation;
return signdata;
} /// <summary>
/// 内容数据转换XML
/// </summary>
/// <param name="type"></param>
/// <param name="obj"></param>
/// <returns></returns>
public static String obj2Xml(Type type, Object obj)
{
XmlSerializer xml = new XmlSerializer(type);
String xmldata = "";
using (MemoryStream stream = new MemoryStream())
{
try
{
xml.Serialize(stream, obj);
xmldata = Encoding.UTF8.GetString(stream.GetBuffer(), 0, (int)stream.Length);
}
catch (Exception)
{
throw;
}
}
return xmldata;
} /// <summary>
/// 内容清洗转换
/// </summary>
/// <param name="xml"></param>
/// <returns></returns>
public static string xmlformat(string xml) {
try { System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(xml); System.IO.StringWriter sw = new System.IO.StringWriter();
using (System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(sw))
{
writer.Indentation = 2; // the Indentation
writer.Formatting = System.Xml.Formatting.Indented;
doc.WriteContentTo(writer);
writer.Close();
}
return sw.ToString();
} catch (Exception ex) {
return xml;
} }
}
}

  

哈哈看了这么多了 咱还没看到请求电子面单的方法是吧  别急

这个类是我自己整合的在项目里的,大老爷们先看看有不足之处 指点指点,应该能看明白!哈哈!案例的是winfrom,这个类没有用上,方法我就不贴出来了,大佬自己去最底下载吧!!!

using Commons.BLL;
using Commons.Model;
using Commons.Settings;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Xml;
using System.Xml.Serialization; namespace Commons.Helpers
{
public class YunDaApiHelper
{
SettingService _settingService=new SettingService();
/// <summary>
/// 韵达电子面单请求url
/// </summary>
private static string _createYunDaUrl;
/// <summary>
/// 取消韵达电子面单url
/// </summary>
private static string _colseYunDaUrl; //韵达ID,密码
private static string _partnerid;
private static string _password; //发件人信息
public static string FHCompany;
public static string FHName;
public static string FHMobile;
public static string FHProvinceName;
public static string FHCityName;
public static string FHExpAreaName;
public static string FHAddress; public YunDaApiHelper()
{//_createYunDaUrl = "http://orderdev.yundasys.com:10110/cus_order/order_interface/interface_receive_order__mailno.php";//测试
//_colseYunDaUrl = "http://orderdev.yundasys.com:10110/cus_order/order_interface/interface_cancel_order.php";//测试
var settings = _settingService.LoadSetting<KdniaoSettings>();
_createYunDaUrl = settings.CreateYunDaUrl;
_colseYunDaUrl = settings.ColseYunDaUrl;
FHCompany = settings.FHCompany;
FHName = settings.FHName;
FHMobile = settings.FHMobile;
FHProvinceName = settings.FHProvinceName;
FHCityName = settings.FHCityName;
FHExpAreaName = settings.FHExpAreaName;
FHAddress = settings.FHAddress;
_partnerid = settings.YdPartnerId;
_password = settings.YdPassword;
} /// <summary>
/// 申请韵达电子面单
/// </summary>
/// <param name="order"></param>
/// <returns></returns>
public YunDaResult CreateYunDaNo(Order order)
{
var model = new YDOrderModel();
var send = new YDSender
{
name = FHName,//发货人名称
company = FHCompany,//发货人公司
mobile = FHMobile,//发货人移动电话或手机
address = FHAddress,//发货人地址,需要将省市区划信息加上,例如:上海市,上海市,青浦区盈港东路7766号
postcode = "", //邮编
city = FHProvinceName + FHCityName + FHExpAreaName,//严格按照国家行政区划,省市区三级,逗号分隔。示例上海市,上海市,青浦区(cod订单必填)
phone = "",//固话
branch = ""
};
order.sender = send;
model.order = order;
try
{
var xml = Obj2Xml(typeof (YDOrderModel), model);
var requestVo = new YunDaRequestModel
{
xmldata = xml,
partnerid = _partnerid,
password = _password,
version = "1.0",
request = "data"
};
var data = SignData(requestVo);
var result = Post(_createYunDaUrl, data);
var msgBody = new XmlDocument();
msgBody.LoadXml(result);
var status = GetXmlValue(msgBody, "status");
var dto = new YunDaResult
{
status = Convert.ToInt32(status),
order_serial_no = GetXmlValue(msgBody, "order_serial_no"),
msg = GetXmlValue(msgBody, "msg"),
mail_no = GetXmlValue(msgBody, "mail_no")
};
return dto; }
catch (Exception ex)
{
var dto = new YunDaResult
{
status = (int) CustomBoolean.False,
msg = ex.ToString()
};
return dto;
}
} /// <summary>
/// 取消韵达电子面单
/// </summary>
/// <param name="xml"></param>
/// <returns></returns>
public YunDaResult ColseYunDaNo(string xml)
{
var requestVo = new YunDaRequestModel
{
xmldata = Xmlformat(xml),
partnerid = _partnerid,
password = _password,
version = "1.0",
request = "cancel_order"
};
try
{
var data = SignData(requestVo);
var result = Post(_colseYunDaUrl, data);
var msgBody = new XmlDocument();
msgBody.LoadXml(result);
var dto = new YunDaResult
{
status = Convert.ToInt32(GetXmlValue(msgBody, "status")),
order_serial_no = GetXmlValue(msgBody, "order_serial_no"),
msg = GetXmlValue(msgBody, "msg")
};
return dto;
}
catch (Exception ex)
{
var dto = new YunDaResult
{
status = (int) CustomBoolean.False,
msg = ex.ToString()
};
return dto;
}
} #region 组装数据以及转化xml数据
/// <summary>
/// 组装主体内容
/// </summary>
/// <param name="requestVo"></param>
/// <returns></returns>
public static string SignData(YunDaRequestModel requestVo)
{
var xmldata = Convert.ToBase64String(System.Text.Encoding.GetEncoding("UTF-8").GetBytes(requestVo.xmldata));
var validation = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(xmldata + requestVo.partnerid + requestVo.password, "MD5").ToLower();
var signdata = "partnerid=" + requestVo.partnerid + "&version=" + requestVo.version + "&request=" + requestVo.request + "&xmldata=" + HttpUtility.UrlEncode(xmldata) + "&validation=" + validation;
return signdata;
} /// <summary>
/// 内容数据转换XML
/// </summary>
/// <param name="type"></param>
/// <param name="obj"></param>
/// <returns></returns>
public static string Obj2Xml(Type type, object obj)
{
var xml = new XmlSerializer(type);
var xmldata = "";
using (var stream = new MemoryStream())
{
try
{
xml.Serialize(stream, obj);
xmldata = Encoding.UTF8.GetString(stream.GetBuffer(), , (int)stream.Length);
}
catch (Exception)
{
throw;
}
}
return xmldata;
} /// <summary>
/// 内容清洗转换
/// </summary>
/// <param name="xml"></param>
/// <returns></returns>
public static string Xmlformat(string xml)
{
try
{
var doc = new System.Xml.XmlDocument();
doc.LoadXml(xml);
var sw = new System.IO.StringWriter();
using (var writer = new System.Xml.XmlTextWriter(sw))
{
writer.Indentation = ; // the Indentation
writer.Formatting = System.Xml.Formatting.Indented;
doc.WriteContentTo(writer);
writer.Close();
}
return sw.ToString();
}
catch (Exception ex)
{
return xml;
} }
#endregion #region Post数据请求
public static HttpWebResponse Post(string url, IDictionary<string, string> parameters)
{
var request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded"; //如果需要POST数据
if (!(parameters == null || parameters.Count == ))
{
var buffer = new StringBuilder();
var i = ;
foreach (var key in parameters.Keys)
{
buffer.AppendFormat(i > ? "&{0}={1}" : "{0}={1}", key, parameters[key]);
i++;
}
var data = Encoding.UTF8.GetBytes(buffer.ToString());
using (var stream = request.GetRequestStream())
{
stream.Write(data, , data.Length);
}
}
return request.GetResponse() as HttpWebResponse;
} public static string Post(string url, string postdata)
{
try
{
var request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
var data = Encoding.UTF8.GetBytes(postdata.ToString());
using (Stream stream = request.GetRequestStream())
{
stream.Write(data, , data.Length);
}
var response = request.GetResponse() as HttpWebResponse;
var sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
var outMessage = sr.ReadToEnd();
sr.Close();
return outMessage;
}
catch (Exception ex)
{
throw ex;
}
}
#endregion #region MyRegion
/// <summary>
/// XML读取对应的值
/// </summary>
/// <param name="msgBody">xml</param>
/// <param name="nodeName">节点名称</param>
/// <returns>返回节点值</returns>
public static string GetXmlValue(XmlDocument msgBody, string nodeName)
{
var fromUserName = msgBody.GetElementsByTagName(nodeName).Item();
return fromUserName?.InnerText;
}
#endregion
}
}
SettingService   这个是系统配置参数,应该没毛病哈哈!
so,下边咱来看看案例的界面

账号:韵达的客户号

密码:是韵达二维码VIP客户端的《接口联调密码》

结语

案例很简单,但是有包含蛮多东东的,各位大佬只要是搞通一个,那估摸着就都没问题了!

链接:https://pan.baidu.com/s/1T3X8-TLorn5R8nZfpKkqOg 密码:m645      ------地址要是挂了,各位直接联系我哈!

好了!各位大老爷觉着这篇文章要是不错就点个赞咯

 

C#对接----韵达开发平台--取电子面单的更多相关文章

  1. java快速开发平台可视化开发表单

    XJR java快速开发平台,简单的理解就是:开发人员以某种编程语言或者某几种编程语言(比如:目前流行的多种web技术,包括springboot, JPA,Druid, Activiti,Lombok ...

  2. 基于PHP的对接电子面单接口平台案例

    电子面单接口目前有三种对接方式,快递电子面单接口.菜鸟电子面单接口和快递鸟电子面单接口.这三种接口各有特点. 一.电子面单接口定义 1. 快递电子面单接口:快递公司自己开发的电子面单服务, 商家使用必 ...

  3. 各种电子面单_Api接口

    电子面单是一种通过热敏纸打印输出纸质物流面单的物流服务.通过热感应显示文字,打印速度比传统针式打印速度提升4~6倍.电子面单以接口形式嵌入到自己的系统.网站上,可以在自己的平台操作打印电子面单.   ...

  4. 基于PHP的对接免费电子面单接口平台的案例-快宝开放平台

    一.电子面单对接平台 电子面单对接平台分为两类: 1 .各大快递公司自有的电子面单接口开放平台:对接起来麻烦,需要每个快递公司分别调试接口,费时费力. 2 .第三方快递开放平台:如快宝开放平台(htt ...

  5. 各种电子面单Api接口免费对接-快宝开放平台

    1.什么是电子面单? 快递公司联合向商家提供的一种通过热敏纸打印输出纸质物流面单的物流服务,并且承载分单自动化算法等数据服务,是快递行业赋能的基础产品和服务. 2.电子面单长什么样? 各快递公司有自己 ...

  6. SNF快速开发平台MVC-EasyUI3.9之-WebApi和MVC-controller层接收的json字符串的取值方法和调用后台服务方法

    最近项目组很多人问我,从前台页面传到后台controller控制层或者WebApi 时如何取值和运算操作. 今天就都大家一个在框架内一个取值技巧 前台JS调用代码: 1.下面是选中一行数据后右键点击时 ...

  7. 英伟达GPU 嵌入式开发平台

    英伟达GPU  嵌入式开发平台 1.         JETSON TX1 开发者组件 JETSON TX1 开发者组件是视觉计算的全功能 开发平台,旨在让您能够快速地安装和运行. 该组件带有 Lin ...

  8. 菜鸟电子面单对接技术方案(link)

    一.背景 快递业务日新月异,收发快递是生活中不可缺少的一部分了,特别是做微商的商家,每天发送大量的快递.填写快递单已经成为过去式,快递小哥上门收件的时候,都使用手持的中端设备,再也不用客户填写快递单了 ...

  9. Java对接拼多多开放平台API(加密上云等全流程)

    前言 本文为[小小赫下士 blog]原创,搬运请保留本段,或请在醒目位置设置原文地址和原作者. 作者:小小赫下士 原文地址:Java对接拼多多开放平台API(加密上云等全流程) 本文章为企业ERP(I ...

随机推荐

  1. 【java】java反射初探 ——“当类也学会照镜子”

    反射的作用   开门见山地说说反射的作用   1.为我们提供了全面的分析类信息的能力 2.动态加载类   我理解的“反射”的意义 (仅个人理解哈)   我理解的java反射机制就是: 提供一套完善而强 ...

  2. 组合拳出击-Self型XSS变废为宝

    前言 作者:米斯特安全攻防实验室-Vulkey_Chen 博客:gh0st.cn 这是一个鸡肋性质的研究,也许有些标题党,请见谅- 本文启发于一些讨论,和自己脑子里冒出来的想法. 组合拳搭配 Self ...

  3. Javascript高级编程学习笔记(26)—— 函数表达式(4)私有变量

    私有变量 严格来讲,JS中没有私有成员的概念,所有对象属性都是公有的. 但是JS中有私有变量的概念 所有在函数中定义的变量都可以认为是私有变量,因为不能在函数外部进行访问 私有变量包括 1.函数参数 ...

  4. Python面向对象4:类的相关函数与属性

    1 类相关函数- issubclass:检测一个类是否是另一个类的子类- isinstance:检测一个对象是否是一个类的实例- hasattr:检测一个对象是否由成员xxx- getattr: ge ...

  5. Java 虚拟机的内存溢出

    在Java虚拟机规范的描述中,除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生 OutOfMemoryError 异常的可能. 在Eclipse中进行JVM参数设置 可以直接通过上方菜单栏的 ...

  6. 第87节:Java中的Bootstrap基础与SQL入门

    第87节:Java中的Bootstrap基础与SQL入门 前言复习 什么是JQ? : write less do more 写更少的代码,做更多的事 找出所有兄弟: $("div" ...

  7. Docker0 网卡删除

    只需执行下面三步就可以了: 1.yum -y install bridge-utils 2.       ifconfig docker0 down 3.  brctl delbr docker0 执 ...

  8. java:当字符串为We Are Happy.经过替换之后的字符串为We%20Are%20Happy

    方法一: public class Solution { public String replaceSpace(StringBuffer str) { String a=str.toString(); ...

  9. 【app】自动化必备之adb使用

    1.1 Adb介绍 adb(android debug bridge)是android sdk自带的一个工具 Adb是用来连接android设备和PC端的桥梁,通过adb工具,用户可以在PC端对手机进 ...

  10. CSS3 Gradient 渐变还能这么玩

    浏览器支持两种类型的渐变:线性渐变 (linear-gradient),径向渐变 (radial-gradient) 渐变在 CSS 中属于一种 Image 类型,可以结合 background-im ...