locked
Reading POST content RRS feed

  • Question

  • User1510859543 posted

    We have a 3rd party API that sends back a HTTP "POST" page to us using a URL that we specify. The ashx page that we are receiving needs to read the data returned from various fields.  Below is how I was told to get each piece of data and just wanted to verify.

    Dim contextData1 As String = CStr((HttpContext.Current.Items("TranRef")))
    Dim contextData2 As String = CStr((HttpContext.Current.Items("TranAmt")))
    etc.

    Thursday, August 13, 2020 9:49 PM

Answers

  • User753101303 posted

    It seems it shoudl work. You could start perhaps with a test page such as:

    <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="WebForm1.aspx.vb" Inherits="vb48.WebForm1" %>
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server" action="PayHandler.ashx">
            <div>
                <input type="text" name="SequenceNo" value="435677" />
                <input type="text" name="Language" value="1" />
                <input type="submit" />
            </div>
        </form>
    </body>
    </html>

    with PayHandler.ashx being:

    Public Class PayHandler
        Implements System.Web.IHttpHandler
        Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
            context.Response.ContentType = "text/plain"
            Dim path = "C:\test\" & Guid.NewGuid().ToString() & ".txt"
            context.Request.SaveAs(path, True)
            For Each key In context.Request.Form.AllKeys
                System.IO.File.AppendAllText(path, System.Environment.NewLine & key & "=" & context.Request.Form(key))
            Next
        End Sub
        ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
            Get
                Return False
            End Get
        End Property
    End Class

    which gives something such as:

    POST /PayHandler.ashx HTTP/1.1
    [headers deleted]
    
    __VIEWSTATE=4mbPiC2V98Q6OKnpWancdfdSn3VfvdxbFeISCmdbVGrQfMxaBdLbzF1JcK2mXGk3jkfgY%2Bz%2FdiGoYR3VQwC1nt0wCyPhzw%2BgcrKhP1vv3RQ%3D&__VIEWSTATEGENERATOR=B6E7D48B&SequenceNo=435677&Language=1
    __VIEWSTATE: 4mbPiC2V98Q6OKnpWancdfdSn3VfvdxbFeISCmdbVGrQfMxaBdLbzF1JcK2mXGk3jkfgY+z/diGoYR3VQwC1nt0wCyPhzw+gcrKhP1vv3RQ=
    __VIEWSTATEGENERATOR: B6E7D48B
    SequenceNo: 435677
    Language: 1

    Edit: are you sure it is currently a POST request rather than a GET request ?

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, August 21, 2020 11:06 AM

All replies

  • User-1330468790 posted

    Hi dlchase,

     

    First of all, HttpContext.Items Property is used to share data between an IHttpModule interface and an IHttpHandler interface during an HTTP request. As you may know, each and every client request passes through the HTTP Pipeline and HTTP Pipeline consists of HTTP Module and HTTP Handler. So If you are writing one custom HTTP Module by Implementing IHttpModule and you want pass some information from this module to the current requested page or any other module, you can use the HttpContext.Current.Items to store the data.

    To summarize, in ASP.NET, HttpContext.Current.Items allows us to hold information for a single request

    dlchase

    We have a 3rd party API that sends back a HTTP "POST" page to us using a URL that we specify.

    However, I can read from above that you will get a "HTTP POST Page" from a 3rd party API.

    How could you get the data from HttpContext.Items Property? It seems like no one stores the data in the HttpContext.Items so that you could not get the data from it.

    If the value is contained in few specific html fields/elements, you could parse the returned html and fetch the value using HtmlAgilityPack.

     

    If I misunderstand your problem, please feel free to let me know.

     

    Best regards,

    Sean

    Friday, August 14, 2020 2:43 AM
  • User1510859543 posted

    We are going to use an online payment system that sends payment receipt information back like accepted/failed, transaction number, etc. that we need to read from our web page (handler ashx page). We will then be able to store those items in our database, etc.  Does that help explain?  Would context.request be a way to do that?

    Friday, August 14, 2020 1:02 PM
  • User-1330468790 posted

    Hi dlchase,

     

    First of all, I think you need to understand what kind of the result you will get from that payment system.

    What I am guessing is that it is like a web api and will return you with a json format information. Correct? 

    However, if it is a html page, you might need to think about using HtmlAgilityPack to parse the page and find out the data you want.

     

    You could refer to below codes for more details.

    Note that I use a button click to simulate the call back from the online payment system and post some information via json string.

    Simulation from the button click:

    <head runat="server">
        <title></title>
      
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    
    </head>
    <body>
       <script>
           $(function () {
               $("#bntSubmit").on('click', function (e) {
    
                   // Initialize the object, before adding data to it.
                   //  { } is declarative shorthand for new Object()
                   var obj = {};
                   obj.accepted = "true";
                   obj.transaction_number = "123456";
    
                   //In order to proper pass a json string, you have to use function JSON.stringfy
                   var jsonData = JSON.stringify(obj);
    
                   $.ajax({
                       url: 'PaymentHandler.ashx',
                       type: 'POST',
                       data: jsonData,
                       success: function (data) {
                           console.log(data);
                           alert("Success :" + data);
                       },
                       error: function (errorText) {
                           alert("Wwoops something went wrong !");
                       }
                   });
    
                   e.preventDefault();
               });
           })
           
       </script>
        <form id="form1" runat="server">
            <div>
                 <button id="bntSubmit">Submit</button>
            </div>
        </form>
    </body>

    PaymentHandler.ashx.cs: To read the json data

    public class PaymentHandler : IHttpHandler
        {
    
            public void ProcessRequest(HttpContext context)
            {
    
                context.Response.ContentType = "text/plain";
    
                try
                {
                    string strJson = new StreamReader(context.Request.InputStream).ReadToEnd();
    
                    //deserialize the object
                    PaymentInfo objPayment = JsonConvert.DeserializeObject<PaymentInfo>(strJson);
                    if (objPayment != null)
                    {
                        string accepted = objPayment.accepted.ToString();
                        string transaction_number = objPayment.transaction_number.ToString();
                        
                        context.Response.Write(string.Format("Accepted :{0} , Transaction Number={1}", accepted, transaction_number));
                    }
                    else
                    {
                        context.Response.Write("No Data");
                    }
                }
                catch (Exception ex)
                {
                    context.Response.Write("Error :" + ex.Message);
                }
    
                
            }
    
            public bool IsReusable
            {
                get
                {
                    return false;
                }
            }
    
            public class PaymentInfo
            {
                public bool accepted { get; set; }
                public int transaction_number { get; set; }
            }
        }

    Demo:

     

    Here I only focus on reading data from the call back. 

    If you still have any question, feel free to let me know.

      

    Best regards,

    Sean

    Monday, August 17, 2020 8:04 AM
  • User1510859543 posted

    I shouldn't need a 3rd party tool to read an html "post" page.  I already know the names of the fields they will send back.

    Monday, August 17, 2020 12:51 PM
  • User-1330468790 posted

    Hi dlchase,

     

    If you don't want to use any other 3rd party tool to read an html page, then I would suggest you use either string methods (e.g. IndexOf) or Regular expression to target the areas.

     

    For example, I will use below html codes to fetch the value inside the label "accepted" and "transaction_number".

    Simulation from the button click:

     <script>
           $(function () {
               $("#bntSubmit").on('click', function (e) {
    
                   // Post a html page to PaymentHandler
                   var html = '<!DOCTYPE html>'
                       + '<html>'
                       + '<head>'
                       + '<title>Page Example</title>'
                       + '</head>'
                       + '<body>'
                       + '<label id="accepted">true</label>'
                       + '<label id="transaction_number">123456</label>'
                       + '</body>'
                       + '</html>';
    
                   // Prove that the PaymentHandler got the page and extract the information.
                   $.ajax({
                       url: 'PaymentHandler.ashx',
                       type: 'POST',
                       data: html,
                       success: function (data) {
                           console.log(data);
                           alert("Success : " + data);
                       },
                       error: function (errorText) {
                           alert("Wwoops something went wrong !");
                       }
                   });
    
                   e.preventDefault();
               });
           })
           
       </script>
        <form id="form1" runat="server">
            <div>
                 <button id="bntSubmit">Submit</button>
            </div>
        </form>

    PaymentHandler.ashx.cs

     public void ProcessRequest(HttpContext context)
            {
    
                context.Response.ContentType = "text/plain";
                string accepted = null, transaction_number = null;
                try
                {
                    string strJson = new StreamReader(context.Request.InputStream).ReadToEnd();
    
    
                    // Regex: [\w ] allow the area contains spaces 
                    Regex regex = new Regex("<label id=\"(?<id>[\\w ]+)\">(?<value>[\\w ]*)<\\/label>");
    
                    MatchCollection matches = regex.Matches(strJson);
                    foreach (Match match in matches)
                    {
                        GroupCollection groups = match.Groups;
                        if (groups["id"] != null)
                        {
                            switch (groups["id"].Value)
                            {
                                case "accepted":
                                    accepted = groups["value"].Value;
                                    break;
                                case "transaction_number":
                                    transaction_number = groups["value"].Value;
                                    break;
                                default: break;
                            }
                        }
    
                    }
    
                    context.Response.Write(string.Format("Accepted :{0} , Transaction Number={1}", accepted, transaction_number));
                }
                catch (Exception ex)
                {
                    context.Response.Write("Error :" + ex.Message);
                }
    
                
            }
    
            public bool IsReusable
            {
                get
                {
                    return false;
                }
            }
    
            public class PaymentInfo
            {
                public bool accepted { get; set; }
                public int transaction_number { get; set; }
            }

    Demo:

     

    Hope this can help you.

    Best regards,

    Sean

    Tuesday, August 18, 2020 8:55 AM
  • User753101303 posted

    Hi,

    If you want to rread posted form fields you'll use https://docs.microsoft.com/en-us/dotnet/api/system.web.httprequest.form?view=netframework-4.8

    If

    Dim contextData1 As String = HttpContext.Current.Request.Form("TranRef")
    Dim contextData2 As String = HttpContext.Current.Request.Form("TranAmt")

    doesn't work you could start by dumping all form fields to see if they are what you expect.

    Tuesday, August 18, 2020 9:21 AM
  • User1510859543 posted

    Below is what they gave me as a sample response POST.

    POST /relay_response HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    Date: Tue, 13 Jan 2009 16:01:41 GMT
    Content-Length: 2585
    Host: testmerchant.com
    
    SequenceNo=435677&Language=1&Tax2Amount=&x_currency_code=CAD&x_ship_to_city=&x
    _method=CC&EXact_Resp_Code=00&CardHoldersName=Susan+Testname&x_email=test
    %40yahoo.com&Authorization_Num=ET141870&MerchantCountry=Canada&Reference_3=&x_
    description=&x_amount=564.30&exact_ctr=%3D%3D%3D%3D%3D%3D%3D
    %3D+TRANSACTION+RECORD+%3D%3D%3D%3D%3D%3D%3D%3D%0A%0AMerchant+Plug-
    in+Test+Store%0A44+King+Street+West%0AVancouver%2C+BC+V6B+4X2%0ACanada

    Thursday, August 20, 2020 7:19 PM
  • User753101303 posted

    Ok and so what if you try:

    Dim contextData1 As String = HttpContext.Current.Request.Form("SequenceNo")
    Thursday, August 20, 2020 8:30 PM
  • User1510859543 posted

    I am using an IHttpHandler (see below). The form content loop brings back nothing.

    Public Class PayHandler : Implements IHttpHandler
    
        Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
    
            context.Response.ContentType = "text/plain"
            'context.Response.Write("Hello World")
    
            Dim loop1 As Integer
            Dim coll As NameValueCollection
            coll = context.Request.Form
            Dim arr1 As String() = coll.AllKeys
            Dim strText As String = ""
    
            Dim path As String = "c:\W_Drive\ReadForm.txt"
    
            If Not File.Exists(path) Then
    
                Using sw As StreamWriter = File.CreateText(path)
                    For loop1 = 0 To arr1.Length - 1
                        sw.WriteLine("Form: " & arr1(loop1))
                    Next
                    If Not context.Request("x_amount") Is Nothing Then
                        sw.WriteLine("x_amount: " & context.Request("x_amount"))
                    End If
                    If Not context.Request("DollarAmount") Is Nothing Then
                        sw.WriteLine("DollarAmount: " & context.Request("DollarAmount"))
                    End If
                    If Not context.Request("x_response_code") Is Nothing Then
                        sw.WriteLine("x_response_code: " & context.Request("x_response_code"))
                    End If
                    If Not context.Request("x_fp_sequence") Is Nothing Then
                        sw.WriteLine("x_fp_sequence: " & context.Request("x_fp_sequence"))
                    End If
                    If Not context.Request("x_fp_timestamp") Is Nothing Then
                        sw.WriteLine("x_fp_timestamp: " & context.Request("x_fp_timestamp"))
                    End If
                End Using
            End If
    
        End Sub
    
        Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
            Get
                Return False
            End Get
        End Property
    
    End Class

    Thursday, August 20, 2020 8:58 PM
  • User753101303 posted

    It seems it shoudl work. You could start perhaps with a test page such as:

    <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="WebForm1.aspx.vb" Inherits="vb48.WebForm1" %>
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server" action="PayHandler.ashx">
            <div>
                <input type="text" name="SequenceNo" value="435677" />
                <input type="text" name="Language" value="1" />
                <input type="submit" />
            </div>
        </form>
    </body>
    </html>

    with PayHandler.ashx being:

    Public Class PayHandler
        Implements System.Web.IHttpHandler
        Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
            context.Response.ContentType = "text/plain"
            Dim path = "C:\test\" & Guid.NewGuid().ToString() & ".txt"
            context.Request.SaveAs(path, True)
            For Each key In context.Request.Form.AllKeys
                System.IO.File.AppendAllText(path, System.Environment.NewLine & key & "=" & context.Request.Form(key))
            Next
        End Sub
        ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
            Get
                Return False
            End Get
        End Property
    End Class

    which gives something such as:

    POST /PayHandler.ashx HTTP/1.1
    [headers deleted]
    
    __VIEWSTATE=4mbPiC2V98Q6OKnpWancdfdSn3VfvdxbFeISCmdbVGrQfMxaBdLbzF1JcK2mXGk3jkfgY%2Bz%2FdiGoYR3VQwC1nt0wCyPhzw%2BgcrKhP1vv3RQ%3D&__VIEWSTATEGENERATOR=B6E7D48B&SequenceNo=435677&Language=1
    __VIEWSTATE: 4mbPiC2V98Q6OKnpWancdfdSn3VfvdxbFeISCmdbVGrQfMxaBdLbzF1JcK2mXGk3jkfgY+z/diGoYR3VQwC1nt0wCyPhzw+gcrKhP1vv3RQ=
    __VIEWSTATEGENERATOR: B6E7D48B
    SequenceNo: 435677
    Language: 1

    Edit: are you sure it is currently a POST request rather than a GET request ?

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, August 21, 2020 11:06 AM
  • User1510859543 posted

    Thank you.

    Friday, August 21, 2020 11:35 AM