Get JSON string from HTTP GET request - c#

Using fiddler to observe this URL:
http://opencaselist.paperlessdebate.com/bin/AllDocs?view=attachments#format=json?|t=allattachments&p=1&l=10&s=filename&d=asc
I find a nice JSON response like this
How do I get this response into a string that I can save in a txt file using C#? Is there a way to turn an HTTP Web Response to a string? Is there something is NewtonSoft JSON that can help me? Are there particular terms that will help me google this more effectively?
Every time I try I just get an HTML version of the web-page at the link and not the JSON data I'm trying to get:
string url = "http://opencaselist.paperlessdebate.com/bin/AllDocs?view=attachments#|t=allattachments&p=1&l=10&s=filename&d=asc";
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.Method = WebRequestMethods.Http.Get;
httpWebRequest.Accept = "text/json";
httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse();
response.Close();

Note that on that screenshot, there are some differences:
the URL is way different: AllAttachements vs AllDocs, but that's minor, I'm pointing it out "just in case"
the PARAMS are way different: the screenshot specifies xpage=plain&outputSyntax=plain and your code - not
the HEADERS are different: your code has Accept=text\json while screenshot has Accept: text/javascript
Have you tried using the same params and headers?
EDIT: also, I've opened up the page from your code, and it actually is a page. After loading, it generates additional requests to
http://opencaselist.paperlessdebate.com/bin/get/XWiki/AllAttachmentsResults?xpage=plain&outputSyntax=plain&offset=1&limit=10&reqNo=1&sort=filename&dir=asc
which, if you download, results in JSON data. No headers at all, simple GET. I've just got the JSON data by simply pasting that URL into Chrome.. I think that you simply use wrong URL.

Related

Cannot access azure storage table using SAS via c#. Works in postman and browser

I am trying to obtain and parse a table from azure storage.
I generated a Shared Access Signature in azure storage explorer.
If I paste the generated url into browser or postman I get the table back as xml.
However, trying to do a HttpWebRequest with the url results in
System.Net.WebException: 'The remote server returned an error: (415) Unsupported Media Type.'
I have tried different content and accept types
const string url = #"https://laptopdeploymentfiles.table.core.windows.net/PaulLoginScript?st=2019-08-21T08%3A10%3A22Z&se=2019-08-22T08%3A10%3A22Z&sp=r&sv=2018-03-28&tn=paulloginscript&sig=***";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
var webResponse = request.GetResponse();
I have tried both
request.Accept = "application/xml";
and
request.ContentType = "application/xml";
but still get the same error.
I have also tried creating and accessing a new table with only simple data. The data accessed via the brower is valid xml, but I still get the same error from a c# app.
The solution was to use both the following contenttype and accept formats
request.Accept = "application/json";
request.ContentType = "application/json";
The solution was to use both the following contenttype and accept formats
request.Accept = "application/json";
request.ContentType = "application/json";
Tested your specific scenario and got it working by using the HttpClient class.
Here's the code I used to get it working:
// Create an instance of HttpClient with the BaseAddress
var client = new HttpClient
{
BaseAddress = new Uri("https://<STORAGE_NAME>.table.core.windows.net/")
};
// Add an Accept Header to tell the service you're expecting the data in JSON format
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Get the actual table
var result = await client.GetAsync("<REST_OF_THE_URI");
When omitting the Accept-header, this code gives the error message:
Atom format is not supported.
EDIT
Taken from Query Tables - Request headers about the Accept header you can specify:
Optional. Specifies the accepted content type of the response payload. Possible values are:
application/atom+xml (versions prior to 2015-12-11 only)
application/json;odata=nometadata
application/json;odata=minimalmetadata
application/json;odata=fullmetadata
I think you need to tell your request what kind of data to expect. Try adding this:
request.ContentType = "application/xml";
I've not tested, so I can't promise this will work. Let me know if it does!
EDIT:
Paul, I tested this code below:
const string url = #" -- used my own xml file in Azure Blob Storage --";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "application/xml";
var webResponse = request.GetResponse();
It worked with no errors. webResponse was populated just fine. I just whipped up a console app and put these 5 lines of code in it, and then stepped through in debug mode to see what would happen.
I wonder what is different about your environment? Could you try isolating these lines of code?
EDIT 2:
Just a thought... are you sure the XML in your file is valid?

c# using TinyUrl Api(getting original address from shortened address)

i found the tinyurl api to shorten the Url. you can see from the link below.
https://blogs.msdn.microsoft.com/bramveen/2009/01/06/converting-url-to-tinyurl-in-c/
And I also want to get original address from my shortened url.
but i can't find that reverse api.
anyone knows how to reverse it?
Looking at the api there is no api to get the reverse. But all tinyurl is doing when you send a HTTP request to tiny url is return a HTTP 301 with the original url in the Location response header. So you could do something like this.
// Creates an HttpWebRequest for the specified URL.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
// Sends the HttpWebRequest and waits for response.
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Now you can use the response object to read the location header value (which is your original url).

HttpWebResponse text does not appear to be JSON

I am making a rest call in which I get a HttpWebResponse that contains data. It seems the data is serialized, and I am trying to get the plain text of the request. I have been using the chrome extension Advanced Rest client, which when calling the same request it is able to display the text version of the json response.
From what I have read on here, you are required to deserialize into the expected object. However, it is pretty clear that chrome plugin has no idea about the object type and can still print out plain text.
Is it possible to do the same in c#?
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/json";
// [code removed for setting json data via stream writer
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// This is where I am trying to figure out how to get plain readable text out of response.GetResponseStream()
}
Edit: If I simply use a StreamReader to get the text from the response stream, I get a bunch of binary data and not the plain json text.
Edit: realized the problem had to do with compression. This can be closed.
I'm not sure if got it right, but you can get the response as a string doing this:
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
Turned out my problem was due to compression. I realized the header contained "Content-Encoding: gzip" so I searched on how to unzip with gzip compression and then the text was proper json. Thanks all

In C#, is it possible to open a URL in the background, without opening a browser?

My code needs to supply some information to a server via a php script.
Basically I want to call www.sitename.com/example.php?var1=1&var2=2&var3=3 but I don't want the browser to open, so Process.Start(URL); won't work.
Since I come to this site to learn and not to get answers, mostly, I will explain what I've done so far and the errors I have gotten. If you know a solution anyway, feel free to skip the next part.
I have looked around, and I saw a solution for using POST:
ASCIIEncoding encoding=new ASCIIEncoding();
string postData="var1=1&var2=2&var3=3";
byte[] data = encoding.GetBytes(postData);
// Prepare web request...
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create("http://localhost/site.php");
myRequest.Method = "POST";
myRequest.ContentType="application/x-www-form-urlencoded";
myRequest.ContentLength = data.Length;
Stream newStream=myRequest.GetRequestStream();
// Send the data.
newStream.Write(data,0,data.Length);
newStream.Close();
However, I require the use of GET not POST. At first I thought the solution might be to change myRequest.Method = "POST"; to GET, but this didn't work because that's not how GET works, it pulls data from the URL.
So, then I attempted to change the previous code to:
HttpwebRequest myRequest= (HttpWebRequest)WebRequest.Create("http://localhost/site.php" + postData);
Stream newStream = myRequest.GetRequestStream();
newStream.Close()
Under the logic that it would call the URL, which would (hopefully) initiate the GET_ request on the php script, and then life would be dandy. This however resulted in the following error:
A first chance exception of type 'System.Net.ProtocolViolationException' occurred in System.dll
An unhandled exception of type 'System.Net.ProtocolViolationException' occurred in System.dll
Additional information: Cannot send a content-body with this verb-type.
Any help is appreciated, and thanks.
string postData="var1=1&var2=2&var3=3";
// Prepare web request...
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(
"http://yourserver/site.php?" + postData);
myRequest.Method = "GET";
var resp =(HttpWebResponse) myRequest.GetResponse();
var result = new StreamReader(resp.GetResponseStream()).ReadToEnd();
Or maybe even simpler:
var data = new WebClient().DownloadString("http://yourserver/site.php?var1=1&var2=2&var3=3");
See the WebClient class for more options
You mostly seem to have gone down the right route:
string postData="var1=1&var2=2&var3=3";
// Prepare web request...
HttpwebRequest myRequest= (HttpWebRequest)WebRequest.Create(
"http://localhost/site.php?" + postData);
// Send the data.
myRequest.GetResponse();
Note that I've added the ? at the end of site.php.
We don't have to fiddle around with the request stream since that's all about putting things in the body of a request - and as you've stated, a GET request has its data in the URL, not in its body.
The easiest way is to use WebClient class. Using it it's just 2 lines of code, just supply your URL and use methods like DownloadString.

Can I send an empty HTTP POST WebRequest object from C# to IIS?

Do I need to just slap some random garbage data in a WebRequest object to get by the HTTP status code 411 restriction on IIS?
I have an HttpPost action method in an MVC 3 app that consumes a POST request with all the relevant information passed in the querystring (no body needed).
[HttpPost] public ActionResult SignUp(string email) { ... }
It worked great from Visual Studio's built in web host, Cassini. Unfortunately, once the MVC code was live on IIS [7.5 on 2008 R2], the server is pitching back an HTTP error code when I hit it from my outside C# form app.
The remote server returned an error:
(411) Length Required.
Here is the calling code:
WebRequest request = WebRequest.Create("http://somewhere.com/signup/?email=a#b.com");
request.Method = "POST";
using (WebResponse response = request.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (StreamReader responseReader = new StreamReader(responseStream)) {
// Do something with responseReader.ReadToEnd();
}
Turns out you can get this to go through by simply slapping an empty content length on the request before you send it.
WebRequest request = WebRequest.Create("http://somewhere.com/signup/?email=a#b.com");
request.Method = "POST";
request.ContentLength = 0;
Not sure how explicitly giving an empty length vs. implying one makes a difference, but IIS was happy after I did. There are probably other ways around this, but this seems simple enough.
I believe you are required to set a Content-Length header anytime you post a request to a web server:
http://msdn.microsoft.com/en-us/library/system.web.httprequest.contentlength.aspx
You could try a GET request to test it.

Categories