7

i am making a request to a 3rd party RESTful service using Microsoft's HttpClient. It works flawlessly (and is very easy to implement) except for this one instance. Here is a breakdown from the provider as to what is occurring during the error:

"The way the POST to the group resource works is that when it completes, it does a HTTP 302 redirect to the group instance resource. What appears to be happening is that your HTTP Client is sending the proper authentication information to the POST, which creates the group resource, but when it handles the GET for the HTTP 302 request, it is not sending the right credentials and is getting a 401 response. Can you check your client library and make sure its sending HTTP auth parameters properly on redirects?"

Here is my POST code:

HttpClient http = new HttpClient(BASE_URL);
http.TransportSettings.Credentials = new NetworkCredential(ACCOUNT_SID, 
                                       ACCOUNT_TOKEN);
HttpResponseMessage httpResponse = http.Post(groupUri, "application/xml", 
                                       HttpContent.Create(xml.ToString()));
result = httpResponse.Content.ReadAsString();

Which brings me to my question; how do I get the authentication parameters to send on this GET redirect using the HttpClient class?

SteveC
  • 15,808
  • 23
  • 102
  • 173
Drew
  • 663
  • 5
  • 15
  • It might be the cookies that they probably use for their session that you are not sending (ask them). Would be strange to request login information after every redirect (unless it's redir to a different webApp or server). – Jaroslav Jandek Jul 19 '10 at 16:08
  • - Jaroslav, i'm waiting on their reply regarding cookies. as far as sending them, are you aware of the proper way? i tried adding this line: http.TransportSettings.Cookies = new CookieContainer(); with no luck... – Drew Jul 19 '10 at 17:29
  • are you using the HttpClient from the WCF REST starter kit? which .net framework? Does HttpClient have any properties for controlling whether to automatically follow redirects? (similar to HttpWebRequest.AllowAutoRedirect)? – James Manning Jul 20 '10 at 05:35
  • FWIW, I don't believe the starter kit is (or was) supported, and it's since been killed, so long-term you might go a different route. http://blogs.msdn.com/b/endpoint/archive/2010/01/06/introducing-wcf-webhttp-services-in-net-4.aspx – James Manning Jul 20 '10 at 05:44
  • 1
    the 3rd party made an update to their system and the redirect is no longer necessary, problem solved :) -James, thanks for the recommendation. that article is excellent and although my current company is not using .Net 4, i will be pushing for it in the months to come. – Drew Jul 21 '10 at 00:21
  • @Drew, could you answer your question for the benefit of others reading through unanswered questions? Thanks. – Nimrod Feb 08 '11 at 19:49

1 Answers1

1

I had a similar problem and at the end I added a form with a WebBrowser control. Whithout calling form.Show() I can tell him to navigate to an URL, click buttons and all. Here is the class that controls that form:

public class Nav
{
    FormNav formNav = new FormNav();
    public string Source
    {
        get
        {
            mshtml.HTMLDocument doc = (mshtml.HTMLDocument)formNav.webBrowser.Document.DomDocument;
            return doc.documentElement.innerHTML;
        }
    }

    public void GoTo(string Url)
    {
        formNav.webBrowser.Navigate(Url);
        Wait();
    }

    public void Fill(string Field, string Value)
    {
        formNav.webBrowser.Document.GetElementById(Field).InnerText = Value;
    }

    public void Click(string Element)
    {
        formNav.webBrowser.Document.GetElementById(Element).InvokeMember("click");
        Wait();
        Application.DoEvents();
    }

    public void Wait()
    {
        const int TIMEOUT = 30;

        formNav.Ready = false;
        DateTime start = DateTime.Now;
        TimeSpan span;

        do
        {
            Application.DoEvents();
            span = DateTime.Now.Subtract(start);
        } while (!formNav.Ready && span.Seconds < TIMEOUT);
    }

    public void Dispose()
    {
        formNav.Dispose();
    }
}

And here is the code for the form (some extra code is needed to disable the clicking sound).

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public partial class FormNav : Form
{
    private const int FEATURE_DISABLE_NAVIGATION_SOUNDS = 21;
    private const int SET_FEATURE_ON_THREAD = 0x00000001;
    private const int SET_FEATURE_ON_PROCESS = 0x00000002;
    private const int SET_FEATURE_IN_REGISTRY = 0x00000004;
    private const int SET_FEATURE_ON_THREAD_LOCALMACHINE = 0x00000008;
    private const int SET_FEATURE_ON_THREAD_INTRANET = 0x00000010;
    private const int SET_FEATURE_ON_THREAD_TRUSTED = 0x00000020;
    private const int SET_FEATURE_ON_THREAD_INTERNET = 0x00000040;
    private const int SET_FEATURE_ON_THREAD_RESTRICTED = 0x00000080;

    [DllImport("urlmon.dll")]
    [PreserveSig]
    [return: MarshalAs(UnmanagedType.Error)]
    static extern int CoInternetSetFeatureEnabled(
        int FeactureEntry,
        [MarshalAs(UnmanagedType.U4)] int dwFlags,
        bool fEnable);

    public bool Ready;

    public FormNav()
    {
        InitializeComponent();
        Ready = true;

        int feature = FEATURE_DISABLE_NAVIGATION_SOUNDS;
        CoInternetSetFeatureEnabled(feature, SET_FEATURE_ON_PROCESS, true);
    }

    private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        Ready = true;
    }
}

And the Microsoft Html Object COM Library should be added if the source code is needed.

Jaime Oro
  • 9,899
  • 8
  • 31
  • 39