2

I need to post to another url / server, however I need to add in other values before it goes to the other url / server. So I would like to post back to my own server, add in the values to the "post" then redirect to the new url.

I've done some searching and there are several answers about doing similar on stackoverflow. Including one particularly good one that I can't find anymore that gave 3 or 4 different examples. Post Method and Redirect With Some Values Without Form C# | Post Data To Url and Redirect | Post form data using HttpWebRequest

However they all seem to create a new set of values to post rather than retrieving the current set of post values and then adding to them. One of them indicated that I couldn't post using Response.Redirect(). So specifically ...

  1. How can I retrieve the current "post" and add my own values to it.
  2. How can I then send the user to another url with that posted data? I want the user to go to a different page after adding my own values on the server.

There's a chance this is a duplicate (with the magnitude of questions on stack it's quite possible) ... if someone can find the answers somewhere else please let me know. I'm working on code currently and will add that to the question the minute I have it ... later tonight.

Edit #1

    public ActionResult Index(FormCollection form)
    {
        //string[] outGoingPostValues = new string[Request.Form.AllKeys.Length + 2];

        string[] incomingPostValues = Request.Form.AllKeys;
        foreach (string t in incomingPostValues)
        {
            Response.Write(t + ": " + Request.Form[t] + "<br>");
        }

        // add in two new keys
        Response.Write("Value1: " + "value1" + "<br>");
        Response.Write("Value2: " + "value2" + "<br>");

        var url = "http://newURL.com";
        WebRequest request = WebRequest.Create(url);
        request.Method = "POST";

        return Redirect("http://someurl.com");
  }

I'm currently trying to test it out by redirecting to my own view and trying to print out the following ...

@{
string[] outGoingPostValues = new string[Request.Form.AllKeys.Length + 2];

string[] incomingPostValues = Response. ?????
foreach (string key in incomingPostValues)
{
    Html.Raw(key);
}  
}
Community
  • 1
  • 1
Kevin Donde
  • 912
  • 3
  • 15
  • 32
  • 1
    what server do you have? classic asp? mvc? web api? – Steve Aug 15 '16 at 21:20
  • I'm working with asp.net mvc. – Kevin Donde Aug 16 '16 at 01:20
  • Are those new values that you are adding sensitive info? – Vadim K. Aug 16 '16 at 16:00
  • jk_xp Imran Ali I can't currently see my way past this question because we can't seem to send the user to another url (in the browser) with added post data. A redirect supposedly doesn't contain "post" data. So I've upped you guys for your assistance but whoever modifies their answer to be most accurate I'll accept in terms of the actual blocker I'll accept for an answer. Even all the options from this answer http://stackoverflow.com/questions/4015324/http-request-with-post/4015346#4015346 all seem to return a response or wait for a response not provided by the user. Hope that's correct. – Kevin Donde Aug 16 '16 at 18:55

2 Answers2

2

I assume you don't have control over the app you are redirecting to. In this case I don't see why approach from this question wouldn't work for you? Unless the values you are adding are sensitive info.

You can do the following:

  1. Get the post data from user.
  2. Massage it as you need, add any new values that you need.
  3. Render a form with massaged values into client response.
  4. Add javascript snippet that would post the form to the other page on load.

Sample code:

 Dictionary<string, string> postData = new Dictionary<string, string>();
 foreach (string key in Request.Form.AllKeys)
 {
        postData.Add(key, Request.Form[key]);
 }
 postData.Add("new-key", "new-value"); //add new values here.
 ViewBag.formPostData = postData;

In a view:

@using (@Html.BeginForm(null, null, FormMethod.Post, new { @action = "http://redirect.com/", @id = "redirectForm" }))
{
    foreach (KeyValuePair<string, string> item in @ViewBag.formPostData)
    {
        @Html.Hidden(item.Key, item.Value);
    }
}


<script type="text/javascript">
    $(document).ready(function () {
        var form = $('#redirectForm');
        if (form) {
            form.submit();
        }
    })
</script>

EDIT:

If the new values are sensitive, I'm afraid there wouldn't be an easy way to accomplish what you want w/o having control over another app. You can execute HttpRequest on the server side with appropriate post parameters as mentioned in other answers and then render the response to the user, but they would still see YOUR url at the top. And resources from the other site such as images, css, etc. might not work properly. And you need to understand that your scenario creates a lot of security concerns.

Community
  • 1
  • 1
Vadim K.
  • 1,081
  • 1
  • 14
  • 26
  • The fields that I'm adding are sensitive and so I can't send them to the view or client in any way ... Thanks.:) – Kevin Donde Aug 16 '16 at 16:31
  • Thanks for your help JK_xp. I'm not entirely familiar with the security concerns you're speaking of ... I just don't understand how it is any different than me saying
    ?
    – Kevin Donde Aug 16 '16 at 16:56
  • 1
    Your scenario looks like [CSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery). When you do
    the request originates from user browser, browser makes post request. When you do HttpRequest from your code - the request originates from your web server. Is that what you're asking?
    – Vadim K. Aug 16 '16 at 17:03
  • Yes ... kind of without the malicious intent. Ultimately companies do this all the time. Another scenario similar to mine that I've done before is when one company sends a user to a hosted pay page by a payment processor
    that will then take an authorization or payment on that page and then the user will then get sent back to us via configuration on their side. This is for a different situation but ultimately this solution could be used there to make that more secure as well.
    – Kevin Donde Aug 16 '16 at 17:11
  • 1
    The scenario that you've just described for a payment processor is true, and those systems are specifically designed for that. Paypal for exam wants you to communicate to it on the backend to obtain a transaction token, and then you redirect a user w/ that token to Paypal page. User doesn't see your sensitive data (like your Paypal credentials) but only the token. So in your original question, my guess that you want to do the same - authenticate user with YOUR credentials, w/o user to see it. The redirect website MUST BE designed to support such scenarios. if it doesn't - then it is a problem. – Vadim K. Aug 16 '16 at 17:23
  • Jk Thanks for your help. It appears that I can't initially do what I'm hoping to and might have to go with some version of what you suggested. We will need to contact this other company we're integrating with and ask them exactly what they want us to do in order to make our integration more secure. In terms of not allowing that sensitive data to be trapped on the page in html or javascript. – Kevin Donde Aug 16 '16 at 18:41
1

You probably need to do something like How to Get the HTTP Post data in C#? to get the data from the post.

Then edit the data however you wish to. Then send the data to the new website using a HttpResponse or Webclient with the POST condition (if there is authentication involved you should look into saving the cookies and sending those over too). Your sources seem to show you how to do that.

Looking at your edit, it seems you forgot to do some things so here is some sample code:

        WebRequest request = WebRequest.Create ("http://www.contoso.com/PostAccepter.aspx ");

        // Set the Method property of the request to POST.
        request.Method = "POST";

        // Create POST data and convert it to a byte array.
        string postData = "This is a test that posts this string to a Web server.";

        byte[] byteArray = Encoding.UTF8.GetBytes (postData);

        // Set the ContentType property of the WebRequest.
        request.ContentType = "application/x-www-form-urlencoded";

        // Set the ContentLength property of the WebRequest.
        request.ContentLength = byteArray.Length;
        // Get the request stream.
        Stream dataStream = request.GetRequestStream ();

        // Write the data to the request stream.
        dataStream.Write (byteArray, 0, byteArray.Length);

        // Close the Stream object.
        dataStream.Close ();

Taken from How to: Send Data Using the WebRequest Class

Community
  • 1
  • 1
Imran Ali
  • 104
  • 13
  • Will a web client or httpResponse transfer control to the user? I basically want to say "take the user here, with this extra data. – Kevin Donde Aug 16 '16 at 01:21
  • 1
    Looking at [How to: Redirect Users to Another Page](https://msdn.microsoft.com/en-us/library/540y83hx.aspx) this should redirect your user. – Imran Ali Aug 16 '16 at 14:34
  • I don't understand how the user gets directed to the other url with the new post data in your example? I would normally want to say Response.Redirect("url"), however the Response object doesn't know anything about WebRequest object ... does it? – Kevin Donde Aug 16 '16 at 16:49
  • 1
    Hmm okay, are you looking for something like [this](http://stackoverflow.com/a/6062248/6126321) ?? – Imran Ali Aug 16 '16 at 17:25
  • 1
    Okay so looking deeper into this, it seems to suggest on [this](http://stackoverflow.com/a/31840993/6126321) answer, that you can use Response.Redirect(). – Imran Ali Aug 16 '16 at 17:46
  • 1
    Looking at that ... It indicates that I could "Wait for a response back" however I can't wait because I need the user take action on that page. So I can't redirect on a successful response because I have to send the user there to create that response. Thanks for your help Imran. I think JK is correct and I've seen it in multiple different answers that I can't post in a redirect because by definition a redirect doesn't contain "post" data. I would've thought that there would've been some way to derive from the response object to allow code to execute and then include the extra values. Alas ... – Kevin Donde Aug 16 '16 at 18:38