6

I'm building an application in ASP.NET MVC (using C#) and I would like to know how I can perform calls like curl http://www.mywebsite.com/clients_list.xml inside my controller Basically I would like to build a kind of REST API to perform actions such as show edit and delete, such as Twitter API.

But unfortunately until now I didn't find anything besides that cURL for windows on this website: http://curl.haxx.se/

So I don't know if is there any traditional way to retrieve this kind of call from URL with methods like post delete and put on the requests, etc...

I just would like to know an easy way to perform commands like curl inside my controller on my ASP.NET MVC Application.


UPDATE:

Hi so I managed to make GET Requests but now I'm having a serious problem in retrieve POST Request for example, I'm using the update status API from Twitter that in curl would work like this:

curl -u user:password -d "status=playing with cURL and the Twitter API" http://twitter.com/statuses/update.xml

but on my ASP.NET MVC application I'm doing like this inside my custom function:

string responseText = String.Empty;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://twitter.com/statuses/update.xml");
request.Method = "POST";
request.Credentials = new NetworkCredential("username", "password");
request.Headers.Add("status", "Tweeting from ASP.NET MVC C#");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
    responseText = sr.ReadToEnd();
}
return responseText;

Now the problem is that this request is returning 403 Forbidden, I really don't know why if it works perfectly on curl

:\


UPDATE:

I finally manage to get it working, but probably there's a way to make it cleaner and beautiful, as I'm new on C# I'll need more knowledge to do it, the way the POST params are passed makes me very confused because is a lot of code to just pass params.

Well, I've created a Gist - http://gist.github.com/215900 , so everybody feel free to revise it as you will. Thanks for your help çağdaş

also follow the code here:

public string TwitterCurl()
{
    //PREVENT RESPONSE 417 - EXPECTATION FAILED
    System.Net.ServicePointManager.Expect100Continue = false;

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://twitter.com/statuses/update.xml");
    request.Method = "POST";
    request.Credentials = new NetworkCredential("twitterUsername", "twitterPassword");

    //DECLARE POST PARAMS
    string headerVars = String.Format("status={0}", "Tweeting from ASP.NET MVC C#");
    request.ContentLength = headerVars.Length;

    //SEND INFORMATION
    using (StreamWriter streamWriter = new StreamWriter(request.GetRequestStream(), ASCIIEncoding.ASCII))
    {
        streamWriter.Write(headerVars);
        streamWriter.Close();
    }

    //RETRIEVE RESPONSE
    string responseText = String.Empty;
    using (StreamReader sr = new StreamReader(request.GetResponse().GetResponseStream()))
    {
        responseText = sr.ReadToEnd();
    }

    return responseText;

    /*
    //I'M NOT SURE WHAT THIS IS FOR            
        request.Timeout = 500000;
        request.ContentType = "application/x-www-form-urlencoded";
        request.UserAgent = "Custom Twitter Agent";
        #if USE_PROXY
            request.Proxy = new WebProxy("http://localhost:3000", false);
        #endif
    */
}
Ciaran Donoghue
  • 800
  • 3
  • 22
  • 46
zanona
  • 12,345
  • 25
  • 86
  • 141
  • Are those username and passwords parameteres supposed to be network credentials or simple post data? I don't know the twitter API, so it would be better if you explain what exactly you are trying to do. – Çağdaş Tekin Oct 22 '09 at 10:54
  • BTW, it appears that you could get a 403 forbidden status if you reached ; 1. 1,000 total updates per day limit. 2. 250 total direct messages per day limit. 3. 150 API requests per hour limit. http://help.twitter.com/forums/10711/entries/15364 – Çağdaş Tekin Oct 22 '09 at 11:01
  • sorry, well, in this case it's trying to connect to my twitter account from http://twitter.com/statuses/update.xml, so if you try to access this from your browser you will see that it asks for a username and password so the credentials on this case would be my twitter account username and password, which I was thinking that would be the same of curl -u username:password ... So in this method the application would connect to my twitter account post a new tweet sending the parameter "status"+ credentials, and retrieving the response that twitter will send back a xml file in this case. – zanona Oct 22 '09 at 11:02
  • thanks, fortunately this rate limit with twitter was not reached yet, I still can do it via curl right now, but not with c# – zanona Oct 22 '09 at 11:04
  • 1
    I couldn't find the information on how that status param should be written. Because if that should be in the post data, then your example is wrong. I'll still edit my answer and provide an example posting data. – Çağdaş Tekin Oct 22 '09 at 11:11
  • Sorry for the delay. I've edited my answer now. – Çağdaş Tekin Oct 22 '09 at 12:13

4 Answers4

5

Try using Microsoft.Http.HttpClient. This is what your request would look like

var client = new HttpClient();
client.DefaultHeaders.Authorization = Credential.CreateBasic("username","password");

var form = new HttpUrlEncodedForm();
form.Add("status","Test tweet using Microsoft.Http.HttpClient");
var content = form.CreateHttpContent();

var resp = client.Post("http://www.twitter.com/statuses/update.xml", content);
string result = resp.Content.ReadAsString();

You can find this library and its source included in the WCF REST Starter kit Preview 2, however it can be used independently of the rest of the stuff in there.

P.S. I tested this code on my twitter account and it works.

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • Hi Darrel, Thank for that it looks much simple, but unfortunately by any mistake I cannot find the classes HttpClient and HttpUrlEncodedForm, I already installed this WCF library but I cannot find it, even on Microsoft library, actually theres not Microsoft.Http namespace in here, I'm sure I'm doing something wrong. Sorry – zanona Oct 23 '09 at 07:37
  • On my machine, the dll is here C:\Program Files (x86)\Microsoft WCF REST\WCF REST Starter Kit Preview 2\Assemblies. Also, included in the installer is a zip file that contains the source code. Open that up and the full source is in there. – Darrel Miller Oct 23 '09 at 11:19
2

Example code using HttpWebRequest and HttpWebResponse :

public string GetResponseText(string url) {
    string responseText = String.Empty;
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "GET";
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    using (StreamReader sr = new StreamReader(response.GetResponseStream())) {
        responseText = sr.ReadToEnd();
    }
    return responseText;
}

To POST data :

public string GetResponseText(string url, string postData) {
    string responseText = String.Empty;
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";
    request.ContentLength = postData.Length;
    using (StreamWriter sw = new StreamWriter(request.GetRequestStream())) {
        sw.Write(postData);
    }
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    using (StreamReader sr = new StreamReader(response.GetResponseStream())) {
        responseText = sr.ReadToEnd();
    }
    return responseText;
}
Çağdaş Tekin
  • 16,592
  • 4
  • 49
  • 58
  • thanks a lot for that çağdaş, now I'm having another problem, I've edited the question so you can check in there if you like. thanks again – zanona Oct 22 '09 at 10:30
1

This is the single line of code I use for calls to a RESTful API that returns JSON.

return ((dynamic) JsonConvert.DeserializeObject<ExpandoObject>(
        new WebClient().DownloadString(
            GetUri(surveyId))
    )).data;

Notes

  • The Uri is generated off stage using the surveyId and credentials
  • The 'data' property is part of the de-serialized JSON object returned by the SurveyGizmo API

The Complete Service

public static class SurveyGizmoService
{
    public static string UserName { get { return WebConfigurationManager.AppSettings["SurveyGizmo.UserName"]; } }
    public static string Password { get { return WebConfigurationManager.AppSettings["SurveyGizmo.Password"]; } }
    public static string ApiUri { get { return WebConfigurationManager.AppSettings["SurveyGizmo.ApiUri"]; } }
    public static string SurveyId { get { return WebConfigurationManager.AppSettings["SurveyGizmo.Survey"]; } }

    public static dynamic GetSurvey(string surveyId = null)
    {
        return ((dynamic) JsonConvert.DeserializeObject<ExpandoObject>(
                new WebClient().DownloadString(
                    GetUri(surveyId))
            )).data;
    }

    private static Uri GetUri(string surveyId = null)
    {
        if (surveyId == null) surveyId = SurveyId;
        return new UriBuilder(ApiUri)
                {
                        Path = "/head/survey/" + surveyId,
                        Query = String.Format("user:pass={0}:{1}", UserName, Password)
                }.Uri;
    }
}
biofractal
  • 18,963
  • 12
  • 70
  • 116
0

Look into the System.Net.WebClient class. It should offer the functionality you require. For finer grained control, you might find WebRequest to be more useful, but WebClient seems the best fit for your needs.

spender
  • 117,338
  • 33
  • 229
  • 351