3

I am attempting to connect to Cloudant (a couch-style DB) from a .Net MVC application. I am following the guidelines for consuming a web API using the HttpClient, as illustrated here: http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client

I have two methods so far -- one to get a document and one to create a document -- and both have errors. The Get method returns Unauthorized and the Post method returns MethodNotAllowed.

The client is created like this:

    private HttpClient CreateLdstnCouchClient()
    {
        // TODO: Consider using WebRequestHandler to set properties


        HttpClient client = new HttpClient();
        client.BaseAddress = new Uri(_couchUrl);

        // Accept JSON
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));


        return client;
    }

The Get method is:

    public override string GetDocumentJson(string id)
    {
        string url = "/" + id;

        HttpResponseMessage response = new HttpResponseMessage();
        string strContent = "";

        using (var client = CreateLdstnCouchClient())
        {
            response = client.GetAsync(url).Result;

            if (response.IsSuccessStatusCode)
            {
                strContent = response.Content.ReadAsStringAsync().Result;
            }
            else
            {
                // DEBUG
                strContent = response.StatusCode.ToString();
                LslTrace.Write("Failed to get data from couch");
            }
        }

        return strContent;
    }

The Post method is:

    public override string CreateDocument(object serializableObject)
    {
        string url = CouchApi.CREATE_DOCUMENT_POST;

        HttpResponseMessage response = new HttpResponseMessage();

        string strContent = "";

        using (var client = CreateLdstnCouchClient())
        {

            response = client.PostAsJsonAsync(url, serializableObject).Result;
            strContent = response.Content.ReadAsStringAsync().Result;
        }

        if (response.IsSuccessStatusCode)
        {
            return strContent;
        }
        else
        {
            LslTrace.Write("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            return response.StatusCode.ToString();
        }
    }

URLs are per the API documentation: https://username:password@username.cloudant.com.

I am very confused by what is going on and having a lot of trouble finding examples. Thanks for your help!

Thomas

1 Answers1

7

With the HttpClient, you need to do the following to authenticate correctly (assuming you use basic auth):

HttpClientHandler handler = new HttpClientHandler();
handler.Credentials = new NetworkCredential(_userName, _password);
HttpClient client = new HttpClient(handler) {
    BaseAddress = new Uri(_couchUrl)
};

You should not specify the username/password in the _couchUrl - HttpClient doesn't support that.

I can't see your implementation of PostAsJsonAsync or the complete Url your are building, but you can try inspecting / logging response.ReasonPhrase when an error occurs to get a hint as to what went wrong.

Will Holley
  • 1,745
  • 10
  • 11
  • 1
    I've posted a really simple example showing how to call the Cloudant API from c#, have a look at https://github.com/cloudant/haengematte/blob/master/c%23/dotNet-45/Program.cs – Will Holley Jun 11 '13 at 12:09
  • I'd also suggest taking at look at one of the CouchDB API wrappers for .NET. Personally, I like [MyCouch](https://github.com/danielwertheim/mycouch) but [LoveSeat](https://github.com/soitgoes/LoveSeat) and [Divan](https://github.com/foretagsplatsen/Divan) are also good options. – Will Holley Jun 11 '13 at 12:14