前言

分享一篇关于在电商系统中同步物流轨迹到本地服务器的文章,当前方案使用了快递100做为数据来源接口,这个接口是收费的,不过提供的功能还是非常强大的,有专门的售后维护团队。也有免费的方案,类似于快递鸟,不过数据出现问题就凉凉了

正文

实现思路大概分为三大步:

第一步:提交订阅信息到快递100的接口

第二步:快递100收到请求后会对回调地址进行跟踪,将快递信息推送给回调接口

第三步:回调接口收到Post推送的数据后,进行逻辑处理

注意:回调的地址建议单独部署一个API项目,不要放在主程序下面;或者在提交订阅时要求对回调进行签名验证。

下面附上详细代码:

Subscribe类

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using WoT.Infrastructure.Helper.Xml;
using WoT.Model.Inventory;
using WoT.ViewModel.Dtos.Inventory;

namespace WoT.SyscTraceSys
{
    /// <summary>
    /// 订阅物流轨迹
    /// </summary>
    public class Subscribe
    {
        //拿到授权的Key
        private static string key = ConfigurationManager.AppSettings["SubscribeKey"];

        //请求的url
        private static string reqUrl = "http://www.kuaidi100.com/poll";

        //回调url
        private static string callbackurl = "http://你的域名/api/kd100/callback";

        /// <summary>
        /// 发送订阅指令
        /// </summary>
        /// <param name="invoce">发货单</param>
        /// <param name="shipperCode">快递公司</param>
        /// <returns></returns>
        public static KD100Result SendPost(Invoice invoce, string shipperCode = "SF")
        {
            StringBuilder param = new StringBuilder();
            KD100Result kdResult = new KD100Result();

            param.Append("<?xml version='1.0' encoding='UTF-8'?>")
                .AppendFormat("<orderRequest>")
                .AppendFormat("<company>{0}</company>", GetCom(shipperCode))
                .AppendFormat("<number>{0}</number>", invoce.LogisticCode)
                .AppendFormat("<from></from>")
                .AppendFormat("<to></to>")
                .AppendFormat("<key>{0}</key>", key)
                .AppendFormat("<parameters><callbackurl>{0}</callbackurl><resultv2>1</resultv2></parameters>", callbackurl)
                .Append("</orderRequest>");

            NameValueCollection postvals = new NameValueCollection();
            postvals.Add("schema", "xml");
            postvals.Add("param", param.ToString());
            try
            {
                using (WebClient wc = new WebClient())
                {
                    string rlt = System.Text.Encoding.UTF8.GetString(wc.UploadValues(reqUrl, "POST", postvals));
                    kdResult = XmlExpand.DESerializer<KD100Result>(rlt);
                }
            }
            catch (Exception ex)
            {
                , message = ex.Message };
            }
            return kdResult;
        }

        /// <summary>
        /// 获取com
        /// </summary>
        /// <param name="shipperCode"></param>
        /// <returns></returns>
        private static string GetCom(string shipperCode)
        {
            string com = "shunfeng";
            switch (shipperCode)
            {
                case "EMS":
                    com = "ems";
                    break;
                case "SF":
                    com = "shunfeng";
                    break;
                case "STO":
                    com = "shentong";
                    break;
                case "YD":
                    com = "yunda";
                    break;
                case "YTO":
                    com = "yuantong";
                    break;
                case "YZPY":
                    com = "youzhengguonei";
                    break;
                case "ZJS":
                    com = "zhaijisong";
                    break;
                case "ZTO":
                    com = "zhongtong";
                    break;
                case "DBL":
                    com = "debangwuliu";
                    break;
                case "JD":
                    com = "debangwuliu";
                    break;
                default:
                    break;
            }
            return com;
        }
    }
}

Subscribe

GetCom()方法是获取获取快递公司的标示编号,我在数据库中只存了快递简称,所以需要通过这种方式获取,如果是存在数据库的就可以直接从数据库获取了。
DESerializer()方法将xml字符串转化为实体对象,关于实现的详情在前面C#操作Xml树的扩展类一节中有讲到。
ConfigurationManager.AppSettings["SubscribeKey"];是读取配置文件,获取快递100对商户授权的Key,配置代码如下:在appSettings节点下添加

KD100Result类

    /// <summary>
    /// 快递100返回结果
    /// </summary>
    [Serializable]
    [XmlType("orderResponse")]
    public class KD100Result
    {
        /// <summary>
        ///
        /// </summary>
        [XmlElement("result")]
        public bool result { get; set; }

        /// <summary>
        ///
        /// </summary>
        [XmlElement("returnCode")]
        public int returnCode { get; set; }

        /// <summary>
        ///
        /// </summary>
        [XmlElement("message")]
        public string message { get; set; }
    }

回调接口Action

        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("callback")]
        public void callback()
        {
            StringBuilder sb = new StringBuilder();
            DateTime now = DateTime.Now;
            pushResponse push = new pushResponse()
            {
                Result = false,
                ReturnCode = ,
                Message = "没有拉取到相关数据"
            };

            HttpContext context = HttpContext.Current;
            if (!context.Request.RequestType.ToUpper().Equals("POST"))
            {
                context.Response.Write(, "请使用POST提交"));
                context.Response.End();
                return;
            }

            try
            {
                sb.Clear();
                var stream = context.Request.InputStream;
                string param = ReadStream(stream);

                if (string.IsNullOrEmpty(param))
                {
                    context.Response.Write(string.Format("<?xml version='1.0' encoding='UTF-8'?><pushResponse><result>{0}</result><returnCode>{1}</returnCode><message>{2}ee</message></pushResponse>", push.Result, push.ReturnCode, push.Message));
                    context.Response.End();
                    return;
                }

                Dictionary<string, string> dic = new Dictionary<string, string>();

                string[] sp1 = param.Split('&');
                foreach (string s in sp1)
                {
                    int splIdx = s.IndexOf('=');
                    , splIdx);
                    );

                    dic.Add(key.Trim(), value.Trim());
                }
                string cbxml = HttpUtility.UrlDecode(dic["param"], Encoding.UTF8);

                using (ILogisticsTraceService _Service = CoreServiceFactory.Used.Build<ILogisticsTraceService>())
                {
                    push = _Service.PushLogisticsTrace(cbxml);
                }

                sb.Append("<?xml version='1.0' encoding='UTF-8'?>")
                    .AppendFormat("<pushResponse><result>{0}</result>", push.Result)
                    .AppendFormat("<returnCode>{0}</returnCode>", push.ReturnCode)
                    .AppendFormat("<message>{0}</message>", push.Message)
                    .Append("</pushResponse>");

                stream.Close();
                context.Response.Write(sb.ToString());
                context.Response.End();
            }
            catch (Exception)
            {
                context.Response.Write(, "服务器处理错误"));
            }

        }

callback

有需要源码的朋友可以扫描下方二维码加入QQ群,我会把源码分享在QQ群里

PS:欢迎扫描下方二维码,加入QQ群

 
作者:Jacky
声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

在Asp.Net MVC中利用快递100接口实现订阅物流轨迹功能的更多相关文章

  1. Asp.net Mvc中利用ValidationAttribute实现xss过滤

    在网站开发中,需要注意的一个问题就是防范XSS攻击,Asp.net mvc中已经自动为我们提供了这个功能.用户提交数据时时,在生成Action参数的过程中asp.net会对用户提交的数据进行验证,一旦 ...

  2. ASP.NET MVC中利用AuthorizeAttribute实现访问身份是否合法以及Cookie过期问题的处理

    话说来到上海已经快半年了,时光如白驹过隙,稍微不注意,时间就溜走了,倒是没有那么忙碌,闲暇之际来博客园还是比较多的,记得上次在逛博问的时候看到有同志在问MVC中Cookie过期后如何作相关处理,他在阐 ...

  3. ASP.NET MVC 中的IResolver&lt;T&gt; 接口

    在ASP.NET MVC 的源码一些实体对象(比如 ControllerBuilder,ControllerFactory, Filters, ViewEngines 等)不再直接通过关键字new来创 ...

  4. 在ASP.NET MVC中利用Aspose.cells 将查询出的数据导出为excel,并在浏览器中下载。

    正题前的唠叨 本人是才出来工作不久的小白菜一颗,技术很一般,总是会有遇到一些很简单的问题却不知道怎么做,这些问题可能是之前解决过的.发现这个问题,想着提升一下自己的技术水平,将一些学的新的'好'东西记 ...

  5. 在MVC中利用uploadify插件实现上传文件的功能

    趁着近段的空闲时间,开发任务不是很重,就一直想把以前在仓促时间里所写的多文件上传功能改一下,在网上找了很多例子,觉得uploadify还可以,就想用它来试试.实现自己想要的功能.根据官网的开发文档,同 ...

  6. Asp.net MVC WebApi项目的自动接口文档及测试功能打开方法

    https://blog.csdn.net/foren_whb/article/details/78866133

  7. ASP.NET MVC:利用ASP.NET MVC4的IBundleTransform集成LESS

    ASP.NET MVC:利用ASP.NET MVC4的IBundleTransform集成LESS 背景 LESS确实不错,只是每次写完LESS都要手工编译一下有点麻烦(VS插件一直没有安装好),昨天 ...

  8. 【ASP.NET MVC系列】浅谈jqGrid 在ASP.NET MVC中增删改查

    ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...

  9. ASP.NET与ASP.NET MVC 中Cache的总结

    Cache有多种翻译,可以是高速缓冲存储器,也可以是法国的服装品牌,本文只是简单的谈谈就是ASP.NET 中Cache,做过Web应用程序的都知道,如果网站访问量比较大,系统应用程序可以将那些频繁访问 ...

随机推荐

  1. SQLServer 脚本测试

    最近在做大数据同步的工作.很少数据需要特殊清洗算法,每次测试,都测试全部数据,浪费时间,可以只测试那些特殊数据即可(切记).

  2. 二叉树建立,先序、中序、后序遍历(c实现)

    建立树ABC##DE#G##F###,输出 #include <stdio.h> #include <stdlib.h> #define ElemType char //节点声 ...

  3. 运行Dos命令并得到dos的输出文本(使用管道函数CreatePipe和PeekNamedPipe)

    function RunDOS(const CommandLine: string): string;var  HRead, HWrite: THandle;  StartInfo: TStartup ...

  4. linux的学习系列 1---简介

    Linux简介 严格的来讲,Linux 不算是一个操作系统,只是一个 Linux 系统中的内核,即计算机软件与硬件通讯之间的平台:Linux的全称是GNU/Linux,这才算是一个真正意义上的Linu ...

  5. Win10无法连接远程桌面提示“你的凭据不工作”的三个解决方法

    Win10无法连接远程桌面提示"你的凭据不工作"的三个解决方法(转藏) 解决方法一:修改组策略 1.在"开始"窗口运行gpedit.msc,进入计算机配置-&g ...

  6. solr6.6 导入索引数据

    1.什么是core core是solr的一个索引库,可以理解为一个数据库,core可以根据需要,创建多个. 2.创建core 例如,创建一个core,名字叫mycore,就可以用一下命令: E:\so ...

  7. 用SpringCloud进行微服务架构演进

    在<架构师必须要知道的阿里的中台战略与微服务> 中已经阐明选择SpringCloud进行微服务架构实现中台战略,因此下面介绍SpringCloud的一些内容,SpringCloud已经出来 ...

  8. 打造自己Django博客日记

    本教程使用的开发环境 本教程写作时开发环境的系统平台为 Windows 10 (64 位),Python 版本为 3.5.2 (64 位),Django 版本为 1.10.6. 建议尽可能地与教程的开 ...

  9. 前端bug记录

    记录一下前端入门时期遇到的一些bug. 1.同步.异步问题 背景:Javascript语言的执行环境是单线程.即一次只能完成一个任务.若有多个任务则需排队逐个执行——前一个任务完成,再执行后一个任务. ...

  10. Kafka概述及安装部署

    一.Kafka概述 1.Kafka是一个分布式流媒体平台,它有三个关键功能: (1)发布和订阅记录流,类似于消息队列或企业消息传递系统: (2)以容错的持久方式存储记录流: (3)记录发送时处理流. ...