search strings google - c#

How do you enter a search string into Google and then see how many results it gets? I've tried doing this:
string uri = "http://google.com/search?q=" + stringsToSearchFor[0];
string response = wc.UploadString (uri, stringsToSearchFor[0]);
Console.WriteLine ("Response: " + response);
Console.ReadKey (true);
I figured the string response would get relevant information such as how many results there are, but when I run the program, I get this error message: The remote server returned an error: (503) Server Unavailable.

I think it is more comfortable and easier to use the Google API.
There you get the results as string. No more need to filter the input / web page for infos.
If you really want to do it via getting the html coded page, use
var response = new WebClient().DownloadString("https://www.google.com/search?q="+mySearchString);
Before using the WebClient Class you have to import the namespace:
using System.Net;
But remember:
If the search string contains whitespaces you have to replace them with '%20'.
To do so, use the String.Replace-Function.
searchString.Replace(" ","%20");

Change
string uri = "http://google.com/search?q=" + stringsToSearchFor[0];
string response = wc.UploadString (uri, stringsToSearchFor[0]);
to
string uri = "http://google.com/search?q=" + WebUtility.UrlEncode(stringsToSearchFor[0]);
string response = wc.DownloadString(uri);
and It will work...

Related

Twilio download recording to file throwing error on JsonConvert.DeserializeObject()

I'm trying to download my recordings on Twilio to a file on my servers local file system (so I can send them to another storage location), but following the code that I've found is throwing an error on the JsonConvert.DeserializeObject() call.
The code that I found is here (called "Retrieve the actual recording media"): https://www.twilio.com/docs/video/api/recordings-resource#filter-by-participant-sid
Here's the code:
static void Main(string[] args)
{
// Find your Account SID and Auth Token at twilio.com/console
const string apiKeySid = "SKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
const string apiKeySecret = "your_api_key_secret";
const string recordingSid = "RTXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
const string uri = $"https://video.twilio.com/v1/Recordings/{recordingSid}/Media";
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(apiKeySid + ":" + apiKeySecret)));
request.AllowAutoRedirect = false;
string responseBody = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
var mediaLocation = JsonConvert.DeserializeObject<Dictionary<string, string>>(responseBody)["redirect_to"];
Console.WriteLine(mediaLocation);
new WebClient().DownloadFile(mediaLocation, $"{recordingSid}.out");
}
And here's my version:
var twilioRecordingUri = $"https://api.twilio.com/2010-04-01/Accounts/{recording.AccountSid}/Recordings/{recording.Sid}.mp3?Download=true";
var request = (HttpWebRequest)WebRequest.Create(new Uri(twilioRecordingUri));
request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes($"{apiKeySid}:{apiKeySecret}")));
request.ContentType = "audio/mpeg";
//request.Accept = "audio/mpeg";
request.AllowAutoRedirect = false;
var responseBody = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
var deserialized = JsonConvert.DeserializeObject<Dictionary<string, string>>(responseBody);
var mediaLocation = deserialized["redirect_to"];
new WebClient().DownloadFile(mediaLocation, $"{recording.Sid}.out");
But executing that code, it fails on the JsonConvert.Deserialize(), like I mentioned; it throws this generic Json error:
Unexpected character encountered while parsing value: �. Path '', line
0, position 0.
Hovering over my "responseBody" variable does show that it's a really long string of funky characters.
My thought was that I should be adding either the "Accept" or "Content-type" to "audio/mpeg" since that's the type of file that I'm trying to retrieve. But when checking Dev Tools at both the request and response headers, neither the Accept or Content-type ever get my audio/mpeg setting that I just specified.
What's wrong with this code here?
Edit: for anyone that noticed the download URL is different from Twilio's example, I found this page that had the updated URL: How do I get a call recording url in twilio when programming in PHP?
I'm only posting this answer to show what the "working" version looks like. It was #Grungondola 's answer that prompted me. Thanks goes to him (as well as the accepted answer).
private async Task DownloadRecording(RecordingResource recording, string fileName)
{
if (string.IsNullOrEmpty(fileName))
throw new ArgumentNullException("fileName is required when downloading a recording.");
var twilioRecordingUri = $"https://api.twilio.com/2010-04-01/Accounts/{recording.AccountSid}/Recordings/{recording.Sid}.mp3?Download=false";
var request = (HttpWebRequest)WebRequest.Create(new Uri(twilioRecordingUri));
request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes($"{apiKeySid}:{apiKeySecret}")));
request.ContentType = "audio/mpeg";
request.AllowAutoRedirect = false;
var stream = request.GetResponse().GetResponseStream();
var virtualPath = HttpContext.Server.MapPath(fileName);
var fileStream = new FileStream(virtualPath, FileMode.Create);
await stream.CopyToAsync(fileStream);
fileStream.Close();
}
It looks like the call you're trying to make is to download an .mp3 file and not a Dictionary<string, string>, so it's likely hitting an error when attempting to deserialize a string into a type that it doesn't match. What you're probably seeing as a result is a Base64 string, especially based on your description. Without seeing at least a sample of the data, I can't know for sure, but I'd guess that you're downloading the raw .mp3 file instead of the file information with location (redirect_to).
If the result is a pure Base64 string, you should be able to convert it to an array of bytes and write that directly to a file with whatever filename you want. That should get you the mp3 file that you want.

Dynamics 365 Online : REST Api call that has a '%2F' as variable in url

OK, so this has kept me busy for too long. Testing the api call with the SOAPUI or Restlett in Chrome I can get the expected result - a binary that represents a pdf or possibly html. I've highlighted the part of the Url in question in yellow (this does represent a document number that should be downloaded and in the parent system is "130318/HJRWIQ" but we cannot use the '/' in the url thus the 130318%2FHJRWIQ representation of the same in the web-api call.
Chrome Restlett Api test results:
Now, trying to do the same in c# this url returns a '
404 not found
and I suspect that the %2F is somehow encoded back to a '/' again.
Below is two different methods I tried (both doing the same) :
c# methods to download the same response;
internal static string DownloadData(string resourceUrl, string authorizationApi, StringBuilder sb)
{
using (var wc = new WebClient())
{
// copy data to byte[]
wc.Headers.Add("Content-Type", "application/pdf");
wc.Headers.Add("Authorization", authorizationApi);
wc.Headers.Add("OData-MaxVersion", "4.0");
wc.Headers.Add("OData-Version", "4.0");
var data = wc.DownloadData(new Uri(#resourceUrl));
sb.AppendLine(" url used\t" + wc.BaseAddress);
sb.AppendLine(" querystring value\t" + wc.Encoding);
return Convert.ToBase64String(data);
}
}
internal static string DownloadData(string resourceUrl, string authorizationApi, ITracingService trace)
{
try
{
using (var wc = new WebClient())
{
wc.Headers.Add("ContentType", " text/plain");
wc.Headers.Add("Authorization", authorizationApi);
//wc.Headers.Add("Content-Disposition", "attachment; filename='82400200813_-doc.pdf'");
//wc.Headers.Add("Transfer-Encoding", "chunked");
return wc.DownloadString(new Uri(#resourceUrl));
}
}
catch (Exception e)
{
trace.Trace("DOWNLOAD DATA EXCEPTION: \n" + e.Message + "\n" + e.InnerException);
}
return "";
}
The Exception logged as per above :
DOWNLOAD DATA EXCEPTION:
The remote server returned an error: (404) Not Found.
just ignore the string builder and tracing (this is used to debug remotely) as this runs online.
Anyone else ran into this before ? How do I get the url passed correctly ?
EDIT
Even MS reproduced this and does not have a workaround answer - I moved this code to an azure service that could do the get independently and pass the result back;

How to query InfluxDB using WebClient in C#

I'm trying to write a simple query command. Documentaion for http for influxDB is here.
This is what I have so far:
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("root", "root");
var reponse = client.UploadString("http://localhost:8080/query", "db=dbName\"q = SELECT \"something\" FROM \"tableName\" WHERE \"tag\"='valueTag'");
I'm getting "The remote server returned an error: (400) Bad Request.". Is it because the urlencode is not the same as putting as the string for the data part of client.UploadString?
WebClient.UploadString sends data as part of a POST request, which isn't what you want for this operation. Instead, your query should be URL-encoded and sent as HTTP GET parameters in the request URL. This can be achieved using Uri.EscapeUriString and WebClient.DownloadString:
var client = new WebClient();
var queryString = Uri.EscapeUriString("db=dbName&q=SELECT \"something\" FROM \"tableName\" WHERE \"tag\"='valueTag'");
var queryUrl = "http://localhost:8086/query?" + queryString;
var response = client.DownloadString(queryUrl);
Also note that HTTP GET parameters are separated by an ampersand and there must not be whitespace between the key/value names and the = or &. For example ?k1=v1&k2=v2 is well-formed whereas ?k1=v1&k1 = v1 is not.

Googe maps web API The remote server returned an error: (400) Bad Request

Thank you for taking the time to read this, I'm currently working on a web app using google maps api but I keep getting error The remote server returned an error: (400) Bad Request. the below code is recommended and said to work but I just can't seem to get it working. I'm running on localhost and this is within a .cs class.
public string reverseGeocoding(string latlng)
{
//samplelatlng value
//latlng ="- 26.1946929,28.042508699999985"
var requestUri = string.Format("https://maps.googleapis.com/maps/api/geocode/xml?location="+ latlng + "&sensor=false");
var request = WebRequest.Create(requestUri);
var response = request.GetResponse();
var xdoc = XDocument.Load(response.GetResponseStream());
var result = xdoc.Element("GeocodeResponse").Element("result");
var address = result.Element("formatted_address").ToString();
return address;
//var locationElement = result.Element("geometry").Element("location");
//var lat = locationElement.Element("lat");
//var lng = locationElement.Element("lng");
//formatted_address
}
Are you sure the variable latlong is passed in correctly? Usually when you get "Bad Request 400" with public APIs like Google Maps, means there is an actual problem with the request. Make sure there are no spaces in the latlong variable. I would print your requestUri to see what it looks like.
Most of the tutorials I found had location as the parameter it's supposed to be latlng cause I am passing latlng I feel pretty dumb thank you I know.
var requestUri = string.Format("https://maps.googleapis.com/maps/api/geocode/xml?latlng=" + latlng + "&sensor=false");

How to call an external URL from a ASP.NET MVC solution

First post inhere ever. So better make it a good one.
I have a ASP.NET MVC 2 web application in which I have an actionResult I need to do a call for me.
The thing is I need this A.R to handle some data operations and after that I need it to call an external URL which is actually a Company Module that handles sending messages to our company handset phones.
It just needs to call the URL that looks like this:
string url = "http://x.x.x.x/cgi-bin/npcgi?no=" + phoneNumber + "&msg=" + message;
I don't need any return message or anything. Just want to call that external URL which is of course outside the scope of my own web application. (I do not want to Redirect). That URL must be called behind the GUI without the user ever realising. And the page that they are viewing must not be affected.
I tried with:
Server.Execute(url);
However did not work. I've heard that some ppl go about this by having a hidden iFrame on the page. The setting the src to the url one may need and then somehow execute that, to get the call instantiated. It doesn't seem so elegant to me, but if that is the only solution, does anyone have an example as to how that is done. Or if you have a more sleek suggestion I am all ears.
I finally got it working with this piece of code:
string messageToCallInPatient = "The doctor is ready to see you in 5 minutes. Please wait outside room " + roomName;
string url = "http://x.x.x.x/cgi-bin/npcgi?no=" + phoneNumber + "&msg=" +
messageToCallInPatient;
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(string.Format(url));
webReq.Method = "GET";
HttpWebResponse webResponse = (HttpWebResponse)webReq.GetResponse();
//I don't use the response for anything right now. But I might log the response answer later on.
Stream answer = webResponse.GetResponseStream();
StreamReader _recivedAnswer = new StreamReader(answer);
Since you don't expect a return value from the url, simplest way is
After the AR Execution, use Webclient to trigger the URL
Either by HTTP GET or POST (Synchronous or Asynchronous)
Sample code
WebClient wc = new WebClient();
wc.UploadProgressChanged += (sender, evtarg) =>
{
Console.WriteLine(evtarg.ProgressPercentage);
};
wc.UploadDataCompleted += (sender, evtarg) =>
{
String nResult;
if (evtarg.Result != null)
{
nResult = Encoding.ASCII.GetString(evtarg.Result);
Console.WriteLine("STATUS : " + nResult);
}
else
Console.WriteLine("Unexpected Error");
};
String sp= "npcgi??no=" + phoneNumber + "&msg=" + message;
System.Uri uri = new Uri("http://x.x.x.x/cgi-bin/");
wc.UploadDataAsync(uri, System.Text.Encoding.ASCII.GetBytes(sb);
The sample uses HTTP POST and Asynchronous call( So it will return immediately after triggering the URL - Non blocking)
You can use simply " return Redirect(url);"

Categories