1

I need to postAsync with header and content together. In order to get access to a website through Console Application in C#. I have my headers as an HttpHeader object with variable name header and my content named newContent as a string object with __Token, return, Email and Password. Now what I want to do is add newContent to header and then use postAsync(url, header+content) to make my POST request.

public async static void DownloadPage(string url)
{
    CookieContainer cookies = new CookieContainer();
    HttpClientHandler handler = new HttpClientHandler();
    handler.CookieContainer = cookies;

    using (HttpClient client = new HttpClient(handler))
    {
        using (HttpResponseMessage response = client.GetAsync(url).Result)
        {
            //statusCode
            CheckStatusCode(response);
            //header
            HttpHeaders headers = response.Headers;
            //content
            HttpContent content = response.Content;
            //getRequestVerificationToken&createCollection
            string newcontent = CreateCollection(content);

            using(HttpResponseMessage response2 = client.PostAsync(url,))

        }

    }
}

public static string GenerateQueryString(NameValueCollection collection)
{
    var array = (from key in collection.AllKeys
                 from value in collection.GetValues(key)
                 select string.Format("{0}={1}", WebUtility.UrlEncode(key), WebUtility.UrlEncode(value))).ToArray();
    return string.Join("&", array);
}


public static void CheckStatusCode(HttpResponseMessage response)
{
    if (response.StatusCode != HttpStatusCode.OK)
        throw new Exception(String.Format(
       "Server error (HTTP {0}: {1}).",
       response.StatusCode,
       response.ReasonPhrase));
    else
        Console.WriteLine("200");
}
public static string CreateCollection(HttpContent content)
{
    var myContent = content.ReadAsStringAsync().Result;
    HtmlNode.ElementsFlags.Remove("form");
    string html = myContent;
    var doc = new HtmlAgilityPack.HtmlDocument();
    doc.LoadHtml(html);
    var input = doc.DocumentNode.SelectSingleNode("//*[@name='__Token']");
    var token = input.Attributes["value"].Value;
    //add all necessary component to collection
    NameValueCollection collection = new NameValueCollection();
    collection.Add("__Token", token);
    collection.Add("return", "");
    collection.Add("Email", "11111111@hotmail.com");
    collection.Add("Password", "1234");
    var newCollection = GenerateQueryString(collection);
    return newCollection;
}
Puzzle
  • 25
  • 2
  • 2
  • 7

3 Answers3

1

I did the very same thing yesterday. I created a seperate class for my Console App and put the HttpClient stuff in there.

In Main:

_httpCode = theClient.Post(_response, theClient.auth_bearer_token);

In the class:

    public long Post_RedeemVoucher(Response _response, string token)
    {
        string client_URL_voucher_redeem = "https://myurl";

        string body = "mypostBody";

        Task<Response> content = Post(null, client_URL_voucher_redeem, token, body);

        if (content.Exception == null)
        {
            return 200;
        }
        else
            return -1;
    }

Then the call itself:

    async Task<Response> Post(string headers, string URL, string token, string body)
    {
        Response _response = new Response();

        try
        {
            using (HttpClient client = new HttpClient())
            {
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, URL);
                request.Content = new StringContent(body);

                using (HttpResponseMessage response = await client.SendAsync(request))
                {
                    if (!response.IsSuccessStatusCode)
                    {
                        _response.error = response.ReasonPhrase;
                        _response.statusCode = response.StatusCode;

                        return _response;
                    }

                    _response.statusCode = response.StatusCode;
                    _response.httpCode = (long)response.StatusCode;

                    using (HttpContent content = response.Content)
                    {
                        _response.JSON = await content.ReadAsStringAsync().ConfigureAwait(false);
                        return _response;
                    }
                }
            }
        }
        catch (Exception ex)
        {
            _response.ex = ex;
            return _response;
        }
    }

I hope this points you in he right direction!

GrahamJ
  • 528
  • 4
  • 15
1

How about iterating over your Headers and adding them to the Content object:

var content = new StringContent(requestString, Encoding.UTF8);

// Iterate over current headers, as you can't set `Headers` property, only `.Add()` to the object.
foreach (var header in httpHeaders) { 
    content.Headers.Add(header.Key, header.Value.ToString());
}

response = client.PostAsync(Url, content).Result;

Now, they're sent in one method.

Nick Bull
  • 9,518
  • 6
  • 36
  • 58
  • Nice I will try it when I get home and let you know how it goes.l – Puzzle Aug 05 '16 at 14:31
  • One can't add "header" like that...I tried using header.key for name, and header.value.Tostring() for value and it did not work. It was giving the following error Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects. – Puzzle Aug 06 '16 at 05:28
  • I cannot use this as code: `HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url); request.Content = new StringContent(queryString); foreach (var header in headers) { request.Content.Headers.Add(header.Key,header.Value.ToString()); }` @ Nick Bull – Puzzle Aug 06 '16 at 05:29
  • @Puzzle apologies I was answering from my phone, so no IDE to test! What are the values you are inserting? That sounds like a problem with the type of header you're inserting. Make sure it's a valid content header (see here for an example of somebody else getting your error message: http://stackoverflow.com/questions/10679214/how-do-you-set-the-content-type-header-for-an-httpclient-request) – Nick Bull Aug 06 '16 at 09:59
  • So try get back to me regarding your value that you are inserting that doesn't work – Nick Bull Aug 06 '16 at 10:00
  • {Cache-Control: max-age=3600, private Set-Cookie: ASP.NET_SessionId=ov20rdamfxowqrwxhgeajcz4; path=/; HttpOnly, ASP.NET_SessionId=ov20rdamfxowqrwxhgeajcz4; path=/; HttpOnly, otohitsforgery=wLWp7RrD_Ijq2FdghkdKaOGWVV_8QH_naBBphINiJvqHWo1jEEB4kBCuO8egV__cikralJdv31G3CCTjs286j-3SzlQjQcLazLkwsZthjGTIUwl7wYsvslCxDScP5-LhMNrm0PyDpAvGFzTigAC3MQ2; path=/; HttpOnly Date: Sat, 06 Aug 2016 15:16:37 GMT } This is what I am inserting.. But @Nick Bull I need to add the content to the header...no? when I am making my post request doesn't it change something when the header is after the content – Puzzle Aug 06 '16 at 15:17
0

If you are still looking into this you can also add headers at the request level as well as the HttpClient level. This works for me:

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, URL);

request.Content = new StringContent(body);

request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
jayeshkv
  • 2,180
  • 4
  • 24
  • 42
GrahamJ
  • 528
  • 4
  • 15
  • What about the cookies? I cant seem to post request with the cookies I get from my getAsync... – Puzzle Aug 09 '16 at 02:31