I've set up a page to do an HTTP Post with a Json serialized generic list, to a different page in ASP.net. When it goes to the new page though, I can't seem to find the body of the HTTP Post.
This is the method for the post:
public static void SendHttpPost(string json)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:57102/Post.aspx");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
}
}
Although this is the first time I've done this, I presumed you would be able to access the Json using Request.Form or similar, but Request.Form is empty. I've had a good look at the VS degugger and can't see it anywhere in the Request object, but the content length is 68000 bytes, so I'm sure it's in there somewhere!
Can anyone point me in the right direction please? Many thanks
You can retrieve the Request Body using Request.InputStream as shown here : gist.github.com/leggetter/769688 !
Related
This question already has answers here:
Deserialize JSON data with C#
(4 answers)
Closed 1 year ago.
I am a student working on a project. I am trying to use the Yahoo! Finance API as a source for my data https://www.yahoofinanceapi.com . I can use HttpWebRequests to call the API and get the "OK" code, see the code below on how I did it:
string BaseURL = "https://yfapi.net/v6/finance/quote?symbols=AAPL";
string addSymbol = "%2C";
string URL = BaseURL;
foreach (string stock in stocks)
{
URL += addSymbol + stock;
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Headers.Add("X-API-KEY", "[My API key]");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(response.ContentType);
Console.WriteLine(response.StatusCode);
response.ContentType gives back "application/json".
response.StatusCode gives back "OK".
Since the response is a JSON I tried to parse it into a string using .ToString() but this obviously doesn't work. When I print it, it just says "System.Net.HttpWebResponse" instead of the showing the actual data in the JSON.
After that I tried to deserialize it using newtonsoft
Results result = JsonConvert.DeserializeObject<Results>(request.GetResponse().ToString());
where Results is a class I made where there is a list of stocks, Stock is also a class I made with some variables in it with the same names of variables in the JSON response.
I got a JSON response from PostMan when I tested the API, opened the response to see what kind of data it contained.
When I ran my code I got the following error message:
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: S. Path '', line 0, position 0.'
This was as far as I got, I tested a few other methods trying to get this working but this one worked the "best".
My biggest issue at the moment is mapping the response into a c# object.
Anything that can help me understand is appreciated :D
You're trying to serialise the HttpWebResponse object into Results, which means deserialisation won't work.
The data is still wrapped & won't be in the format of the Results object.
The GetResponseStream() method can be used to get the contents of the HTTP response as a stream, which can then be deserialised directly, in this case, using Json.NET.
Replace this section:
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(response.ContentType);
Console.WriteLine(response.StatusCode);
With this:
var serializer = new JsonSerializer();
using (var response = (HttpWebResponse)request.GetResponse())
{
var encoding = Encoding.GetEncoding(response.CharacterSet);
using var responseStream = response.GetResponseStream();
using var reader = new StreamReader(responseStream, encoding);
using (var jsonTextReader = new JsonTextReader(reader))
{
Console.WriteLine(response.ContentType);
Console.WriteLine(response.StatusCode);
Results result = serializer.Deserialize<Results>(jsonTextReader);
}
}
Alternatively, a much better solution if you're using .NET 4.5 <= would be to use HttpClient like below:
private static readonly HttpClient httpClient = new HttpClient();
...
string BaseURL = "https://yfapi.net/v6/finance/quote?symbols=AAPL";
string addSymbol = "%2C";
string URL = BaseURL;
foreach(string stock in stocks) {
URL += addSymbol + stock;
}
client.DefaultRequestHeaders.Add("X-API-KEY", "[My API key]");
var data = await httpClient.GetStringAsync(address);
Results result = JsonConvert.DeserializeObject<Results>(data);
I am using an API to make a post request to a server
(http://example.com)
on the website The form gets filled out with my code but it doesn't actually get submitted. I've seen post where people give an HTML example and do some sort of on click submit method but I don't have access to the form in that way so is there anyway I can submit it?
I'm writing to the form like so...
var ticketData = JsonConvert.SerializeObject(new
{
Summary = "test",
Impact = 1,
DueDate = "2017-12-28",
Priority = 1
}, Formatting.Indented);
using (Stream dataStream = webRequest.GetRequestStream())
{
using (var streamWriter = new StreamWriter(dataStream))
{
using (var writer = new JsonTextWriter(streamWriter))
{
writer.WriteRaw(ticketData);
writer.Close();
}
}
}
HttpWebResponse httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
How do I programmatically submit?
is there like a way to set submit to true? I don't know how to go about doing this
EDIT: as suggested in the comments, added an explanation below.
public async Task PostForm(Uri requestUri, string json)
{
using (var httpClient = new HttpClient())
{
var content = new StringContent(json, Encoding.UTF8, "application/json");
await httpClient.PostAsync(requestUri, content);
}
}
This function uses the HttpClient to post the form data you serialized to json to a specific URL (requesturi). That URL is the URL of the POST action of the website you want to post to
I have a string that uses JsonTextWriter to create a JSON formatted-string. How do I interact with it if I want to store it in an Azure website? I was thinking of using an httpWebRequest like
string webAddr = "http://{url to website}/test.json";
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(webAddr);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "POST";
StringWriter strwriter = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(strwriter);
writer.WriteStartObject();
writer.WritePropertyName("id");
writer.WriteValue(v.id);
writer.WriteEndObject();
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = strwriter.ToString();
streamWriter.Write(json);
}
But I can't seem to figure out how to actually post the JSON to a file. Am I missing anything?
I think that it would be fine to store on the local storage of the VM/website to avoid a CORS issue, unless there is something that Blob storage would benefit over local storage.
You're part way there, next you need to actually dispatch the request:
HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
And you can read through the returned body (if required):
using (httpWebResponse)
{
StreamReader reader = new StreamReader(httpWebResponse.GetResponseStream());
string response_body = reader.ReadToEnd();
}
Assuming you just wanted to dump the body to the file system (for arguments sake):
using (httpWebResponse)
{
...
using (var file = new FileStream("some\path\to\file.json",FileMode.Create,FileAccess.Write,FileShare.None))
{
StreamWriter writer = new StreamWriter(file,Encoding.UTF8);
writer.Write(response_body);
writer.Flush();
}
}
However this won't work for non VM websites, for that you'd probably have to shun the file off to blob storage.
I'm new to JSON & am using VS 2013/C#. Here's the code for the request & response. Pretty straightforward, no?
Request request = new Request();
//request.hosts = ListOfURLs();
request.hosts = "www.cnn.com/www.cisco.com/www.microsoft.com/";
request.callback = "process";
request.key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string output = JsonConvert.SerializeObject(request);
//string test = "hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
try
{
var httpWebRequest = (HttpWebRequest) WebRequest.Create("http://api.mywot.com/0.4/public_link_json2?);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = output;
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
}
}
catch (WebException e)
{
MessageBox.Show(e.ToString());
}
//response = true.
//no response = false
return true;
}
When I run this, I get a 405 error indicating method not allowed.
It seems to me that there are at least two possible problems here: (1) The WoT API (www.mywot.com/wiki/API) requires a GET request w/ a body, & httpWebRequest doesn't allow a GET in the httpWebRequest.Method; or (2) the serialized string isn't serialized properly.
NOTE: In the following I've had to remove the leading "http://" since I don't have enough rep to post more than 2 links.
It should look like:
api.mywot.com/0.4/public_link_json2?hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxx
but instead looks like:
api.mywot.com/0.4/public_link_json2?{"hosts":"www.cnn.com/www.cisco.com/www.microsoft.com/","callback":"process","key":"xxxxxxxxxxxxxxxxxxx"}.
If I browse to:api.mywot.com/0.4/public_link_json2?hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxx; I get the expected response.
If I browse to: api.mywot.com/0.4/public_link_json2?{"hosts":"www.cnn.com/www.cisco.com/www.microsoft.com/","callback":"process","key":"xxxxxxxxxxxxxxxxxxx"}; I get a 403 denied error.
If I hardcode the request & send as a GET like below:
var httpWebRequest = (HttpWebRequest) WebRequest.Create("api.mywot.com/0.4/public_link_json2? + "test"); it also works as expected.
I'd appreciate any help w/ this & hope I've made the problem clear. Thx.
Looks to me like the problem is that you are sending JSON in the URL. According to the API doc that you referenced, the API is expecting regular URL encoded parameters (not JSON), and it will return JSON to you in the body of the response:
Requests
The API consists of a number of interfaces, all of which are called using normal HTTP GET requests to api.mywot.com and return a response in XML or JSON format if successful. HTTP status codes are used for returning error information and parameters are passed using standard URL conventions. The request format is as follows:
http://api.mywot.com/version/interface?param1=value1¶m2=value2
You should not be serializing your request; you should be deserializing the response. All of your tests above bear this out.
I am wondering if HttpWebRequest can be used to fill a MVC model? I am trying to build a MVC 4 application where I take data from a college course listing page and massage it in a few different ways in my View. The examples that I have been seeing around have all taken a response stream and returned a string or have not been formatted for MVC (using console.write). Also, as far as I understand, the data as its being returned isn't in a JSON or XML format. Here is my controller so far...
public ActionResult Index()
{
string postData = "semester=20143Fall+2013+++++++++++++++++++++++++++++++&courseid=&subject=IT++INFORMATION+TECHNOLOGY&college=&campus=1%2C2%2C3%2C4%2C5%2C6%2C7%2C9%2CA%2CB%2CC%2CI%2CL%2CM%2CN%2CP%2CQ%2CR%2CS%2CT%2CW%2CU%2CV%2CX%2CZ&courselevel=&coursenum=&startTime=0600&endTime=2359&days=ALL&All=All+Sections";
byte[] dataArray = Encoding.UTF8.GetBytes (postData);
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create("http://www3.mnsu.edu/courses/selectform.asp");
myRequest.Method = "POST";
myRequest.ContentType = "application/x-www-form-urlencoded";
myRequest.ContentLength = dataArray.Length;
using (WebResponse response = myRequest.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
//insert into a model? Maybe?
}
}
return View();
}
If HttbWebRequest can't be used, is there a way that would work? Or am I completely heading in the wrong direction?
You can using HttpWebRequest and WebResponse to get stream from your college course's web site. Then use HtmlAgilityPack to parse scrap in the stream and insert your desired value into model