Is it possible to pass parameters with an HTTP get request? If so, how should I then do it? I have found an HTTP post requst (link). In that example the string postData is sent to a webserver. I would like to do the same using get instead. Google found this example on HTTP get here. However no parameters are sent to the web server.
My preferred way is this. It handles the escaping and parsing for you.
WebClient webClient = new WebClient();
webClient.QueryString.Add("param1", "value1");
webClient.QueryString.Add("param2", "value2");
string result = webClient.DownloadString("http://theurl.com");
First WebClient is easier to use; GET arguments are specified on the query-string - the only trick is to remember to escape any values:
string address = string.Format(
"http://foobar/somepage?arg1={0}&arg2={1}",
Uri.EscapeDataString("escape me"),
Uri.EscapeDataString("& me !!"));
string text;
using (WebClient client = new WebClient())
{
text = client.DownloadString(address);
}
In a GET request, you pass parameters as part of the query string.
string url = "http://somesite.com?var=12345";
The WebRequest object seems like too much work for me. I prefer to use the WebClient control.
To use this function you just need to create two NameValueCollections holding your parameters and request headers.
Consider the following function:
private static string DoGET(string URL,NameValueCollection QueryStringParameters = null, NameValueCollection RequestHeaders = null)
{
string ResponseText = null;
using (WebClient client = new WebClient())
{
try
{
if (RequestHeaders != null)
{
if (RequestHeaders.Count > 0)
{
foreach (string header in RequestHeaders.AllKeys)
client.Headers.Add(header, RequestHeaders[header]);
}
}
if (QueryStringParameters != null)
{
if (QueryStringParameters.Count > 0)
{
foreach (string parm in QueryStringParameters.AllKeys)
client.QueryString.Add(parm, QueryStringParameters[parm]);
}
}
byte[] ResponseBytes = client.DownloadData(URL);
ResponseText = Encoding.UTF8.GetString(ResponseBytes);
}
catch (WebException exception)
{
if (exception.Response != null)
{
var responseStream = exception.Response.GetResponseStream();
if (responseStream != null)
{
using (var reader = new StreamReader(responseStream))
{
Response.Write(reader.ReadToEnd());
}
}
}
}
}
return ResponseText;
}
Add your querystring parameters (if required) as a NameValueCollection like so.
NameValueCollection QueryStringParameters = new NameValueCollection();
QueryStringParameters.Add("id", "123");
QueryStringParameters.Add("category", "A");
Add your http headers (if required) as a NameValueCollection like so.
NameValueCollection RequestHttpHeaders = new NameValueCollection();
RequestHttpHeaders.Add("Authorization", "Basic bGF3c2912XBANzg5ITppc2ltCzEF");
GET request with multiple params:
curl --request GET --url
http://localhost:8080/todos/?limit=10&offset=2 --header
'content-type:application/json'
You can also pass value directly via URL.
If you want to call method
public static void calling(string name){....}
then you should call usingHttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create("http://localhost:****/Report/calling?name=Priya);
webrequest.Method = "GET";
webrequest.ContentType = "application/text";
Just make sure you are using ?Object = value in URL
Related
I'm receiving a 400 Bad Request error message when posting a pin on Pinterest. It works using Postman, but doesn't work programmatically. Using C#, has anyone been able to successfully post a pin on Pinterest without using the pinsharp wrapper?
private void postPinterest(string messages, string id, string usertoken, string image, string boardname, string username)
{
string link = null;
boardname = boardname.Replace(" ", "-");
string board = username + "/" + boardname;
string url = "https://api.pinterest.com/v1/pins?access_token=" + usertoken;
StringBuilder sb = new StringBuilder();
if (!string.IsNullOrEmpty(board))
sb.Append("&board=" + HttpUtility.UrlEncode(board));
if (!string.IsNullOrEmpty(messages))
sb.Append("¬e=" + HttpUtility.UrlEncode(messages));
if (!string.IsNullOrEmpty(link))
sb.Append("&image_url=" + HttpUtility.UrlEncode(link));
string postdata = sb.ToString().Substring(1);
PostData(url, postdata);
}
private object PostData(string url, string postdata)
{
object json=null;
try
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
// req.Accept = "application/json";
using (var stream = req.GetRequestStream())
{
byte[] bindata = Encoding.ASCII.GetBytes(postdata);
stream.Write(bindata, 0, bindata.Length);
}
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
string response = new StreamReader(resp.GetResponseStream()).ReadToEnd();
json = JsonConvert.DeserializeObject<dynamic>(response);
return json;
}
catch (WebException wex)
{
if (wex.Response != null)
{
using (var errorResponse = (HttpWebResponse)wex.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
string error = reader.ReadToEnd();
return json;
}
}
}
}
return json;
}
EDIT:
It doesn't work using the JSON format or x-www-form-urlencoded format.
I changed the content type to application/x-www-form-urlencoded and now I'm receiving the error message below. I receive 400 Bad Request error using JSON format:
"{\n \"message\": \"405: Method Not Allowed\",\n \"type\": \"http\"\n}"
The problem is the the parameter that you are posting.
In the Api i could find board as a parameter but both note and image comes under field parameter which specifies the return type JSON.
As per documentation on this page you can post in this format
https://api.pinterest.com/v1/boards/anapinskywalker/wanderlust/pins/?
access_token=abcde&
limit=2&
fields=id,link,counts,note
So I tried the following and its getting response
https://api.pinterest.com/v1/boards/?access_token="YourTokenWithoutQuotes"&fields=id%2Ccreator
Would suggest you to first test the Api you are hitting putting a breakpoint inside the PostData function and check if the passed url is in the correct format and compare it with Pininterest API Explorer.
As you might have already received authorization code and access token so I am assuming your post function should be working fine.
public string postPinterest(string access_token,string boardname,string note,string image_url)
{
public string pinSharesEndPoint = "https://api.pinterest.com/v1/pins/?access_token={0}";
var requestUrl = String.Format(pinSharesEndPoint, accessToken);
var message = new
{
board = boardname,
note = note,
image_url = image_url
};
var requestJson = new JavaScriptSerializer().Serialize(message);
var client = new WebClient();
var requestHeaders = new NameValueCollection
{
{"Content-Type", "application/json" },
{"x-li-format", "json" }
};
client.Headers.Add(requestHeaders);
var responseJson = client.UploadString(requestUrl, "POST", requestJson);
var response = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(responseJson);
return response;
}
I have 2 c# asp.net projects. 1 is an api. 1 is consuming this api.
My api:
public class MyApiController : ApiController
{
public dynamic ValidateToken(string token)
{
return myValidationMethod(token);
}
}
Consuming my api from another project:
public class MyController : Controller
{
[HttpPost]
public ActionResult ValidateToken(string token)
{
var url = "http://localhost:1234/myapi/validatetoken";
var parameters = "token=" + token;
using (var client = new WebClient())
{
var result = client.UploadString(url, parameters);
return Json(result);
}
}
}
In project 2 where I consume the api, client.UploadString throws a System.Net.WebException - The remote server returned an error: (404) Not Found.
When I test the api with the chrome rest client it works with http://localhost:1234/myapi/validatetoken?token=myToken
Why can WebClient not find it?
Solved
I got this to work thanks to #BrentMannering with a small change to add content length:
var url = "http://localhost:1234/myapi/validatetoken?token=" + token;
var request = WebRequest.Create(url);
request.Method = "POST";
request.ContentLength = 0; //got an error without this line
var response = request.GetResponse();
var data = response.GetResponseStream();
string result;
using (var sr = new StreamReader(data))
{
result = sr.ReadToEnd();
}
return Json(result);
I don't think UploadString is sending the data as params, so the routing engine on the API side cannot map to an action, hence the 404. According to the MSDN documentation the method is encoding to a Byte[] prior to uploading, this could be part of the problem.
Try using the UploadValues method
var url = "http://localhost:1234/myapi/validatetoken";
var nv = new NameValueCollection { { "token", token } };
using (var client = new WebClient())
{
var result = client.UploadValues(url, nv);
return Json(result);
}
Otherwise to mimic the test you are doing with the chrome client use WebRequest
var url = "http://localhost:1234/myapi/validatetoken?token=" + token;
var request = WebRequest.Create(url);
request.Method = "POST";
var data = request.GetResponse().GetResponseStream();
string result = String.Empty;
using (StreamReader sr = new StreamReader(data))
{
result = sr.ReadToEnd();
}
return Json(result);
WebClient.UploadString method sends an Http POST method. Did you try to access your APIController with a POST method from the test client ? I am assuming your test client sent a GET request and it worked.
There is a different overload where you can mention the Action method type.
var url = "http://localhost:1234/myapi/validatetoken";
var parameters = "token=" + token;
string method = "GET"; //or POST as needed
using (var client = new WebClient())
{
var result = client.UploadString(url,method , parameters);
return Json(result);
}
I have code like the following to do a POST to a server:
string URI = "http://mydomain.com/foo";
string myParameters =
"&token=1234" +
"&text=" + HttpUtility.UrlEncode(someVariable);
using (WebClient wc = new WebClient())
{
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
string HtmlResult = wc.UploadString(URI, myParameters);
}
Is it required to UrlEncode the parameters like I'm doing or does UploadString handle that automatically under the covers? I don't want to risk any type of double encoding.
Yes, it is required to encode them if you use the UploadString method.
But you could use a more intelligent overload for your case (UploadValues):
string URI = "http://mydomain.com/foo";
var values = new NameValueCollection
{
{ "token", "1234" },
{ "text", someVariable },
};
using (var wc = new WebClient())
{
byte[] result = wc.UploadValues(URI, values);
string htmlResult = Encoding.UTF8.GetString(result);
}
Now you no longer need to worry about any encodings. The WebClient will take them into account when sending the request. Also you will notice that I have removed the application/x-www-form-urlencoded you were adding because when you use the UploadValues method this Content-Type header will automatically be added to the request.
I try download file from server with FileWebRequest. But I get error:
Method on download is here:
public string HttpFileGetReq(Uri uri, int reqTimeout, Encoding encoding)
{
try
{
string stringResponse;
var req = (FileWebRequest)WebRequest.Create(uri);
req.Timeout = reqTimeout;
req.Method = WebRequestMethods.File.DownloadFile;
var res = (FileWebResponse)req.GetResponse();
//using (var receiveStream = res.GetResponseStream())
//using (var readStream = new StreamReader(receiveStream,encoding))
//{
// stringResponse = readStream.ReadToEnd();
//}
return stringResponse="0K";
}
catch (WebException webException)
{
throw webException;
}
}
Usage is here:
public dynamic LoadRoomMsg(IAccount account, string roomId)
{
try
{
string uri = string.Format("http://www-pokec.azet.sk/_s/chat/nacitajPrispevky.php?{0}&lok={1}&lastMsg=0&pub=0&prv=0&r=1295633087203&changeroom=1" , account.SessionId, roomId);
var htmlStringResult = HttpFileGetReq(new Uri(uri), ReqTimeout, EncodingType);
//var htmlStringResult = _httpReq.HttpGetReq(new Uri(string.Format("{0}{1}?{2}&lok=", PokecUrl.RoomMsg,account.SessionId,roomId)),
// ReqTimeout, account.Cookies, EncodingType);
if (!string.IsNullOrEmpty(htmlStringResult))
{
return true;
}
return false;
}
catch (Exception exception)
{
throw exception;
}
}
URL on file is here.
I would like read this file to string variable, that’s all. If anyone have some time and can help me I would be very glad to him.
Your URL (http://...) will produce a HttpWebRequest. You can check with the debugger.
Form MSDN:
The FileWebRequest class implements
the WebRequest abstract base class for
Uniform Resource Identifiers (URIs)
that use the file:// scheme to request
local files.
Note the file:// and local files in there.
Tip: Just use the WebClient class.
Rather than implement your own web streams allow the .NET framework to do it all for you with WebClient, for example:
string uri = string.Format(
"http://www-pokec.azet.sk/_s/chat/nacitajPrispevky.php?{0}&lok={1}&lastMsg=0&pub=0&prv=0&r=1295633087203&changeroom=1",
account.SessionId,
roomId);
System.Net.WebClient wc = new System.Net.WebClient();
string webData = wc.DownloadString(uri);
...parse the webdata response here...
Looking at the response from the URL you posted:
{"reason":0}
parsing that should be a simple task with a little string manipulation.
Change FileWebRequest and FileWebResponse to HttpWebRequest and HttpWebResponse.
It doesn't matter that what you're downloading may be a file; as far as the .NET Framework is concerned, you're just retrieving a page from a website.
FileWebRequest is for file:// protocols. Since you're using an http:// url, you want to use HttpWebRequest.
public string HttpFileGetReq(Uri uri, int reqTimeout, Encoding encoding)
{
string stringResponse;
var req = (HttpWebRequest)WebRequest.Create(uri);
req.Timeout = reqTimeout;
var res = (HttpWebResponse)req.GetResponse();
using (var receiveStream = res.GetResponseStream())
{
using (var readStream = new StreamReader(receiveStream,encoding))
{
return readStream.ReadToEnd();
}
}
}
Our company works with another company called iMatrix and they have an API for creating our own forms. They have confirmed that our request is hitting their servers but a response is supposed to come back in 1 of a few ways determined by a parameter. I'm getting a 200 OK response back but no content and a content-length of 0 in the response header.
here is the url:
https://secure4.office2office.com/designcenter/api/imx_api_call.asp
I'm using this class:
namespace WebSumit
{
public enum MethodType
{
POST = 0,
GET = 1
}
public class WebSumitter
{
public WebSumitter()
{
}
public string Submit(string URL, Dictionary<string, string> Parameters, MethodType Method)
{
StringBuilder _Content = new StringBuilder();
string _ParametersString = "";
// Prepare Parameters String
foreach (KeyValuePair<string, string> _Parameter in Parameters)
{
_ParametersString = _ParametersString + (_ParametersString != "" ? "&" : "") + string.Format("{0}={1}", _Parameter.Key, _Parameter.Value);
}
// Initialize Web Request
HttpWebRequest _Request = (HttpWebRequest)WebRequest.Create(URL);
// Request Method
_Request.Method = Method == MethodType.POST ? "POST" : (Method == MethodType.GET ? "GET" : "");
_Request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Win32)";
// Send Request
using (StreamWriter _Writer = new StreamWriter(_Request.GetRequestStream(), Encoding.UTF8))
{
_Writer.Write(_ParametersString);
}
// Initialize Web Response
HttpWebResponse _Response = (HttpWebResponse)_Request.GetResponse();
// Get Response
using (StreamReader _Reader = new StreamReader(_Response.GetResponseStream(), Encoding.UTF8))
{
_Content.Append(_Reader.ReadToEnd());
}
return _Content.ToString();
}
}
}
I cannot post the actual parameters because they are to the live system, but can you look at this code and see if there is anything that is missing?
Thanks!
Several obvious problems:
you're not URL-encoding your query parameters. If there are any spaces or special characters in your values, the server may barf on your input or truncate it.
you're trying to send data in the method body even if the method is GET -- this will fail. You need to stick values on the URL query string if it's a GET.
You're trying to roll your own version of WebClient instead of just using WebClient. Below is a WebClient sample which handles URL-encoding of parameters, handles GET and POST properly, etc.
.
public class WebSumitter
{
public string Submit(string URL, Dictionary<string, string> Parameters, MethodType Method)
{
// Prepare Parameters String
var values = new System.Collections.Specialized.NameValueCollection();
foreach (KeyValuePair<string, string> _Parameter in Parameters)
{
values.Add (_Parameter.Key, _Parameter.Value);
}
WebClient wc = new WebClient();
wc.Headers[HttpRequestHeader.UserAgent] = "Mozilla/4.0 (compatible; MSIE 6.0; Win32)";
if (Method == MethodType.GET)
{
UriBuilder _builder = new UriBuilder(URL);
if (values.Count > 0)
_builder.Query = ToQueryString (values);
string _stringResults = wc.DownloadString(_builder.Uri);
return _stringResults;
}
else if (Method == MethodType.POST)
{
byte[] _byteResults = wc.UploadValues (URL, "POST", values);
string _stringResults = Encoding.UTF8.GetString (_byteResults);
return _stringResults;
}
else
{
throw new NotSupportedException ("Unknown HTTP Method");
}
}
private string ToQueryString(System.Collections.Specialized.NameValueCollection nvc)
{
return "?" + string.Join("&", Array.ConvertAll(nvc.AllKeys,
key => string.Format("{0}={1}", System.Web.HttpUtility.UrlEncode(key), System.Web.HttpUtility.UrlEncode(nvc[key]))));
}
}
Use Fiddler to see whether any response is actually coming back across the network wire. It sounds like the server is sending you an empty 200 OK response.