一、系统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 id="formMain" 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/

C# 前台和后台POST提交信息的实现方法的更多相关文章

  1. ASP.NET前台html页面AJAX提交数据后台ashx页面接收数据

    摘要:最近在写网站,好不容易弄好了需求又变了,没错企业的门户网站硬要弄成后台管理系统一样,没办法作为小工的我只能默默的改.前台HTML页面需要提交数据到后台处理,又不能用form表单,于是乎研究了1天 ...

  2. Yii创建前台和后台登录表单和通过扩展 CWebUser 增加信息到 Yii::app()->user

    我参考了这篇文章来构建项目的前台和后台的目录结构.感谢Andy的这篇文章.按照所有的步骤,您将有单独的前台和后台面板,如: http://localhost/index.php // 前台 http: ...

  3. 【总结-前台发送后台接收表单】MVC提交表单的四种方式

    https://www.cnblogs.com/chenwolong/p/Form.html#commentform 后台控制器接收前台表单参数三种方法: 一.普通参数 HTML标签name 和参数名 ...

  4. 由ASP.NET所谓前台调用后台、后台调用前台想到HTTP——理论篇

    工作两年多了,我会经常尝试给公司小伙伴儿们解决一些问题,几个月下来我发现初入公司的小朋友最爱问的问题就三个 1. 我想前台调用后台的XXX方法怎么弄啊? 2. 我想后台调用前台的XXX JavaScr ...

  5. js前台与后台数据交互-后台调前台(后台调用、注册客户端脚本)

    转自:http://blog.csdn.net/wang379275614/article/details/17049721 客户端脚本一般都在前台,这里讲的是(1)在后台调用前台定义的脚本(2)在后 ...

  6. js前台与后台数据交互

    客户端脚本一般都在前台,这里讲的是(1)在后台调用前台定义的脚本(2)在后台如何注册客户端脚本 用途 何时使用服务器代码向页中添加客户端脚本: u 当客户端脚本的内容依赖于直到运行时才可用的信息时 u ...

  7. ASP.NET中使用JSON方便实现前台与后台的数据交换

    ASP.NET中使用JSON方便实现前台与后台的数据交换 发表于2014/9/13 6:47:08  8652人阅读 分类: ASP.NET Jquery extjs 一.前台向后台请求数据 在页面加 ...

  8. 由ASP.NET所谓前台调用后台、后台调用前台想到HTTP——实践篇(二)

    在由ASP.NET所谓前台调用后台.后台调用前台想到HTTP——理论篇中描述了一下ASP.NET新手的三个问题及相关的HTTP协议内容,在由ASP.NET所谓前台调用后台.后台调用前台想到HTTP—— ...

  9. asp.net 前台绑定后台变量方法总结:<%= %> 和<%# %>的区别

    经常会碰到在前台代码中要使用(或绑定)后台代码中变量值的问题.一般有<%= str%>和<%# str %>两种方式,这里简单总结一下.如有错误或异议之处,敬请各位指教.  一 ...

随机推荐

  1. Layui关闭弹出层并刷新父窗口

    先确保已经引入layui和jquery 再确保初始化layer弹出层 <script> layui.use(['form', 'layer'], function() { var form ...

  2. 部署 laravel项目404错误

    1.nginx 下部署出现404错误 (1)打开php.ini中的php_openssl.dll这个扩展: (2)修改nginx 下的站点目录配置文件(我的是配置在vhost.conf)为: loca ...

  3. linux:用户和组文件解释(/etc/passwd、/etc/shadow、/etc/group、/etc/gshadow)

    一.用户文件:/etc/passwd [root@pinfun6 ~]# cat /etc/passwd root:x:0:0:root:/root:/bin/bash 1 2 3 4 5 6 7 | ...

  4. BZOJ 3189. [Coci2011]Slika

    传送门 有回档操作,考虑离线,这样就知道最终的操作序列了 发现前面的操作会被后面覆盖,干脆直接从后往前操作,如果一个位置以前染色过了那就不用再染色 所以我们可以用 $n$ 个链表维护 $n$ 个行,操 ...

  5. Struts2对于BigDecimal类型的转换问题

    Struts2对常用的数据类型如String.Integer.Double等都添加了转换器进行对应的转换操作. BigDecimal其实也算作是一种常用的数据类型,但Struts2没有对该类型设置转换 ...

  6. vue学习【四】vuex快速入门

    大家好,我是一叶,今天我们继续踩坑.今天的内容是vuex快速入门,页面传值不多的话,不建议vuex,直接props进行父子间传值就行,使用vuex就显得比较臃肿. 我们先预览一下效果,如图1所示. 图 ...

  7. HashMap 的实现原理(1.7)

    参考 :http://wiki.jikexueyuan.com/project/java-collection/hashmap.html https://blog.csdn.net/w22981192 ...

  8. php函数nl2br的反函数br2nl 将html中的br换行符转换为文本输入中的换行符

    下面这几个方法将能够帮你解决这个问题. PHP版将html中的<br />换行符转换为文本框中的换行符: 代码如下: function br2nl($text){ return preg_ ...

  9. [BZOJ1299]巧克力棒(博弈论,线性基)

    [BZOJ1299]巧克力棒 Description TBL和X用巧克力棒玩游戏.每次一人可以从盒子里取出若干条巧克力棒,或是将一根取出的巧克力棒吃掉正整数长度.TBL先手两人轮流,无法操作的人输. ...

  10. Java并发编程实战 第16章 Java内存模型

    什么是内存模型 JMM(Java内存模型)规定了JVM必须遵循一组最小保证,这组保证规定了对变量的写入操作在何时将对其他线程可见. JMM为程序中所有的操作定义了一个偏序关系,称为Happens-Be ...