C#前台和后台POST提交信息的实现方法

一、系统A(官网)与系统B(第三方支付平台)数据交换的方式

       1.1  页面浏览器方式:系统A以构造Form表单的方式,通过系统A客户的浏览器重定向到系统B(向系统B发送请求),B系统完成交易后,将交易结果送给A系统。eg:A系统用户完成注册后在B系统开户

        1.2 后台数据流方式:后台数据流方式分为表单和Json格式返回两种数据格式,开户和交易接口都是使用表单,查询类接口使用JSON;A系统服务器,构造Http协议报文,直接访问B系统,将Http报文发送到B系统,并获取返回的满足Http报文协议的字符流。在数据流的方式下,A系统以表单的方式将数据发送到B系统,B系统收到后进行相应的处理。

现已第三方提供的Pos机自动代扣的接口为例,分别讲解前台和回台数据交换:

          

二、页面浏览器方式

      2.1 以Form表单的形式提交 

           A、 transfer.aspx页面,body内容如下,其中注意body标签的onload事件,form的Action在后台指定;transfer只是中转页面,以供在系统中其他页面只需抛数据到transfer页面,而不关注与第三方的交互,与第三方交互主要由transfer页面完成

            <body onload="sub();">
    <form runat="server">
        <input type="hidden" name="Version" value="<%=Version%>" />
        <input type="hidden" name="CmdId" value="<%=CmdId%>" />
        <input type="hidden" name="MerCustId" value="<%=MerCustId%>" />
        <input type="hidden" name="UsrCustId" value="<%=UsrCustId%>" />
        <input type="hidden" name="OpenAcctId" value="<%=OpenAcctId%>" />
        <input type="hidden" name="TransAmt" value="<%=TransAmt%>" />
        <input type="hidden" name="OrdId" value="<%=OrdId%>" />
        <input type="hidden" name="OrdDate" value="<%=OrdDate%>" />
        <input type="hidden" name="CheckDate" value="<%=CheckDate%>" />
        <input type="hidden" name="RetUrl" value="<%=RetUrl%>" />
        <input type="hidden" name="BgRetUrl" value="<%=BgRetUrl%>" />
        <input type="hidden" name="MerPriv" value="<%=MerPriv%>" />
        <input type="hidden" name="ChkValue" value="<%=ChkValue%>" />
    </form>
    <script type="text/javascript">
        function sub() {
            document.getElementById("formMain").submit();
        }
    </script>
</body>

       B、 transfer.aspx.cs内容如下:

public partial class Interface_POSWithoutCard_Transfer
{
    public readonly string PnrUrl = ChinaPnrInterfaces.GetConfigValue("pnrurl");
    public readonly string Version = ChinaPnrInterfaces.GetConfigValue("pnrversion");
    public readonly string CmdId = "PosWhSave"; //函数名称
    public string MerCustId = string.Empty; //商户ID
    public string UsrCustId = string.Empty; //用户ID(PNRID)
    public string OpenAcctId = string.Empty; //开户银行账号 
    public string TransAmt = string.Empty; //交易金额
    public string OrdId = string.Empty; //订单号
    public string OrdDate = string.Empty; //订单日期
    public string CheckDate = string.Empty; //校验日期
    public string RetUrl = string.Empty; //页面返回
    public string BgRetUrl = string.Empty; //商户后台应答地址
    public string MerPriv = string.Empty; //商户私有域
    public string ChkValue = string.Empty;

    protected void Page_Load(object sender, EventArgs e)
    {
        MerCustId = CurMerCustId;
        UsrCustId = DESEncrypt.Decrypt(Request["UsrCustId"]);
        OpenAcctId = DESEncrypt.Decrypt(Request["OpenAcctId"]);
        TransAmt = DESEncrypt.Decrypt(Request["TransAmt"]);
        CheckDate = DESEncrypt.Decrypt(Request["CheckDate"]);

        OrdId = bll.GetNextOrdId();
        OrdDate = DateTime.Now.ToString("yyyyMMdd");//CurWebUrl
        RetUrl = string.Format("{0}/Interface/POSWithoutCard_Return.aspx?action=frontend&ordid={1}&transamt={2}", CurWebUrl, DESEncrypt.Encrypt(OrdId), DESEncrypt.Encrypt(TransAmt));//第三方支付平台根据此字段获取前后回应地址,注意,由第三方处理完后回传的这部分数据其他内容需要通过Request.Form["Name"]获取,但对于地址后面的action,ordid和transamt需要使用get方式获取;   公路养护车,双排座自卸车,散装饲料运输车厂家价格(http://www.glyhche.com/ 
         BgRetUrl = string.Format("{0}/Interface/POSWithoutCard_Return.aspx?action=backend&ordid={1}&transamt={2}", CurWebUrl, DESEncrypt.Encrypt(OrdId), DESEncrypt.Encrypt(TransAmt));//后台预防返回地址
        formMain.Action = PnrUrl;//地址为第三方提供的接收页面

        if (bll.CreateLog(new dw_poswksave_log_model()
        {
            OrdId = OrdId,
            PnrId = UsrCustId,
            BankId = OpenAcctId,
            TransAmt = float.Parse(TransAmt),
            OrdDate = OrdDate,
            CheckDate = CheckDate
        }))
        {
            ChkValue = ChinaPnrInterfaces.SignChkValue(Version + CmdId + MerCustId + UsrCustId
                + OpenAcctId + TransAmt + OrdId + OrdDate + CheckDate + RetUrl + BgRetUrl + MerPriv);
        }

        Response.ContentEncoding = Encoding.GetEncoding("gb2312");
    }

    protected string DateToString(string strDate)
    {
        DateTime date;
        if (!DateTime.TryParse(strDate, out date))
            date = DateTime.Now;

        return date.ToString("yyyyMMdd");
    }

    protected string MoneyToString(string strMoney)
    {
        if (string.IsNullOrEmpty(strMoney))
            strMoney = "0";

        return float.Parse(strMoney).ToString("F2");
    }
}

C、Return.aspx 页面用于接收第三方支付平台回传的结果

        <body>
    <% if (ShowUserTip) { %>
    <div class="err">
        <div class="info">
            <div>
                响应信息
            </div>
            <div>
                <div>代码:<%=RespHFCode%></div>
                <div>描述:<%=RespHFDesc%></div>
            </div>
            <div><%=RespHFCode.Equals(HFOK) ? "" : "请重新提交!"%></div>
        </div>
        <div class="bot">
            <input type="button" value="关闭此窗口" onclick="window.close();" />
        </div>
    </div>
    <% } %>
</body>

D、Return.aspx.cs文件如下:

  public readonly string HFOK = "000";
    public string RespHFString = string.Empty;
    public string RespHFCode = string.Empty;
    public string RespHFDesc = string.Empty;
    public string OrdId = string.Empty;
    public string TransAmt = string.Empty;
    public bool ShowUserTip = false;

    protected void Page_Load(object sender, EventArgs e)
    {
        string action = Request["action"];//对应transfer传递参数时放在地址后的参数
        if (!string.IsNullOrEmpty(action))
        {
            RespHFString = "RECV_ORD_ID_" + Request.Form["TrxId"];//在页面显示
            RespHFCode = Request.Form["RespCode"];
            RespHFDesc = Request.Form["RespDesc"];
            OrdId = DESEncrypt.Decrypt(Request["ordid"]);
            TransAmt = DESEncrypt.Decrypt(Request["transamt"]);

            switch (action)
            {
                case "frontend":
                    ShowUserTip = true;//前台回复,将结果显示在页面上
                    UpdatePosLog();
                    break;
                case "backend"://后台响应直接存储就可以了,但需要判断前台是否已经处理,否则会造成数据重复处理
                    string checkValue = Request.Form["CmdId"].Trim()
                                      + Request.Form["RespCode"].Trim()
                                      + Request.Form["MerCustId"].Trim()
                                      + Request.Form["UsrCustId"].Trim()
                                      + Request.Form["OpenAcctId"].Trim()
                                      + Request.Form["TransAmt"].Trim()
                                      + Request.Form["OrdId"].Trim()
                                      + Request.Form["OrdDate"].Trim()
                                      + Request.Form["CheckDate"].Trim()
                                      + Request.Form["TrxId"].Trim()
                                      + Request.Form["RetUrl"].Trim()
                                      + Request.Form["BgRetUrl"].Trim()
                                      + Request.Form["MerPriv"].Trim();

                    if (ChinaPnrInterfaces.DecChkValue(checkValue, Request.Form["ChkValue"]).Equals("0"))
                    {
                        UpdatePosLog();
                    }
                    break;
            }
        }
    }

三、后台数据流方式

        3.1、使用HttpWebRequest对象,Post数据:

                string TransferUrl = string.Empty;
                string postData = string.Empty;
                string userPnrID = dr["pnrid"].ToString();
                string bankID = dr["BankId"].ToString();
                string checkDate = dr["CheckDate"].ToString();
                string repayment_account = Decimal.Round(Convert.ToDecimal(TransNullOrEmpty(dr["repayment_account"].ToString())), 2).ToString();

                TransferUrl = string.Format("{0}/Interface/POSWithoutCard_Transfer.aspx", strWebSiteUrl);//需要请求的页面

                postData = string.Format("UsrCustId={0}&OpenAcctId={1}&TransAmt={2}&CheckDate={3}",
                DESEncrypt.Encrypt(userPnrID), DESEncrypt.Encrypt(bankID), DESEncrypt.Encrypt(repayment_account), DESEncrypt.Encrypt(checkDate));//传递的参数


                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(TransferUrl);//后台请求页面

                string s = postData;
                Encoding encoding = Encoding.GetEncoding("GB2312");//GB2312,注意页面的编码,否则会出现乱码
                byte[] requestBytes = encoding.GetBytes(postData);

                req.Method = "POST";
                req.ContentType = "application/x-www-form-urlencoded";
                req.ContentLength = requestBytes.Length;
                Stream requestStream = req.GetRequestStream();
                requestStream.Write(requestBytes, 0, requestBytes.Length);
                requestStream.Close();

                HttpWebResponse res = (HttpWebResponse)req.GetResponse();
                StreamReader sr = new StreamReader(res.GetResponseStream(), System.Text.Encoding.GetEncoding("GB2312"));
                string backstr = sr.ReadToEnd();//可以读取到从页面返回的结果,以数据流的形式。
                // Response.Write(backstr);      
                sr.Close();
                res.Close();

       3.2、使用WebClient对象:

string postData = string.Format("UsrCustId={0}&OpenAcctId={1}&TransAmt={2}&CheckDate={3}",
                DESEncrypt.Encrypt(userPnrID), DESEncrypt.Encrypt(bankID), DESEncrypt.Encrypt(repayment_account), DESEncrypt.Encrypt(checkDate));//这里即为传递的参数,可以用工具抓包分析,也可以自己分析,主要是form里面每一个name都要加进来  

byte[] postData = Encoding.UTF8.GetBytes(postString);//编码,尤其是汉字,事先要看下抓取网页的编码方式  

string TransferUrl= string.Format("{0}/Interface/POSWithoutCard_Transfer.aspx", strWebSiteUrl);//需要请求的页面

WebClient webClient = new WebClient();  

webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");//采取POST方式必须加的header,如果改为GET方式的话就去掉这句话即可  

byte[] responseData = webClient.UploadData(TransferUrlurl, "POST", postData);//得到返回字符流  

string srcString = Encoding.UTF8.GetString(responseData);//解码  

3.3、WebBrowser对象(没用过,暂时不讨论,具体可参考http://www.cnblogs.com/peterzb/archive/2009/07/12/1521787.html)

转自:http://blog.itpub.net/28699126/viewspace-1127499/

更多相关文章
  • shell下,进程的前台与后台运行跟系统任务相关的几个命令:fg.bg.jobs.&.ctrl+z1. & 最经常被用到这个用在一个命令的最后,可以把这个命令放到后台执行2. ctrl + z可以将一个正在前台执行的命令放到后台,并且暂停3. jobs查看当前有多少在后台运行的命令4 ...
  • Asp.Net前台调用后台变量1.Asp.Net中几种相似的标记符号: < %=...%>< %#... %>< % %>< %@ %>解释及用法答: < %#... %>: 是在绑定控件DataBind()方法执行时被执行,用于数据绑定如 ...
  • 应用程序不管在后台还是前台都会执行 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void ...
  • 线程系列01,前台线程,后台线程,线程同步
    在控制台应用程序集中,Main方法开始的是一个线程.如果要再创建线程,需要用到System.Threading这个命名空间.   □ 线程是怎样工作的? CLR维护着一个叫"thread scheduler"的机制,这个机制与操作系统交互."thread schedul ...
  • WordPress前台后台页面打开慢的解决方法
    wp_deregister_style( 'open-sans' wp_register_style( 'open-sans', wp_enqueue_style('open-sans', '' add_action( 'init', 'remove_open_sans' ); 保存之后速度就恢复了 ...
  • 简单示意: 用户提交信息----->微信服务器(腾讯的)---->公众号业务服务器(公司的) 公众平台用户提交信息后,微信服务器将发送GET请求到填写的URL上,并且带上四个参数: 参数 描述 signature 微信加密签名 timestamp 时间戳 nonce 随机数 echost ...
  •   我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败.如何让命令提交后不受本地关闭终端窗口/网络断开连接的干扰呢?下面举了一些例子, 您可以针对不同的场景选择不同的方式来处理这个问题.nohup/ ...
  • LINUX让进程在后台可靠运行的几种方法转自 http://www.ibm.com/developerworks/cn/linux/l-cn-nohup/我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中 ...
一周排行
  • 安装Horizon View Configuration ToolVMware Horizon View Configuration Tool (以下简称为vCT), 现在版本为1.0, 本产品的用途为帮助用户自动安 ...
  • 如何开发一个简单的HTML5Canvas小游戏
    原文:How to make a simple HTML5 Canvas game 想要快 ...
  • 全新以最小化包安装了64位的CentOS6.3系统,作为本地的Web服务器使用,现记录全过程第六步,安装mysql5.5数据库v5.5.28mysql从5.5版本开始,不再使用./configure编译,而是使用cm ...
  • 2015-12-06第七天课程笔记
    复习 模块 模块支持从逻辑上组织Python代码.当代码量变得相当大的时候,我们最好把代码 ...
  • hadoop oozie 在Hadoop中执行的任务有时候需要把多个Map/Reduce作业连接到一起,这样才能够达到目的.在Hadoop生态圈中,有一种相对比较新的组件叫做Oozie,它让我们可以把多个Map/Re ...
  • 这两天在看IBM商业价值研究院的一篇文章,名为<中国地产企业的未来发展之路>.看完之后,觉的是精品,按照习惯就对其进行了分解.分解完了之后,给出两点总结:1.如果要给客户做咨询或服务(可以是软件),先设定 ...
  •  内存是拿来用的不是拿来看的  原文链接:http://bbs.linuxtone.org/thread--1.html IT运维专家网--"自由平等,互助分享!"  内存是拿来用的不 ...
  • 美国老人哈里.莱伯曼74岁退休后,6年里经常去一所老人俱乐部下棋,消磨晚年时光.一天他又去下棋时,女办事员告诉他,往常那位棋友因身体不适,不能前来陪他下棋了.看到老人一副失望万分的样子,热情的办事员建议他到画室去转一 ...
  • 以下的文章主要讲述的是Mysql临时表的具体使用方案,并提醒测试Mysql临时表查看它们是否真的比对大量数据库的运行查询要快.如果相关的数据很好地索引,临时表可能一点不快.标签:Mysql当工作在非常大的表上时,你可 ...
  • 一.概述 大家都知道selenium支持不同的浏览器,而webdriver启动项目时需要启动浏览器的driver,于是乎配置不同的浏览器来启动不同的driver势在必行了, 下面请看代码: 二.编写一个初始化sele ...