I am developing an application for the Windows Phone 7. I am making a GET request to a JSON service. The return type of the request is an object.
My question is, how do I create a string from the information in the object. The code below is what I am using to make the request and process the response.
HttpWebRequest carRequest = (HttpWebRequest)WebRequest.Create(carUrl);
carRequest.Method = "GET";
carRequest.BeginGetResponse(new AsyncCallback(ProcessResponse), carRequest);
private void ProcessResponse(IAsyncResult asyncResult)
{
HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
WebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
StreamReader sr = new StreamReader(response.GetResponseStream());
Car.car = (Car)JsonConvert.DeserializeObject(sr.ReadToEnd(), typeof(Car));
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
NavigationService.Navigate(new Uri("/SearchResults.xaml", UriKind.Relative));
});
}
Why not use a WebClient?
private void DownloadString()
{
var wc = new WebClient();
wc.DownloadStringCompleted += MyHandler;
wc.DownloadStringAsync(carUrl);
}
void MyHandler(object sender, DownloadStringCompletedEventArgs e)
{
var result = e.Result;
}
Note that this is a general solution for downloading a string. If you are resolving JSON, then use one of the methods included in JSON.Net for this kind of interaction.
Also note that you may want to stash your result object somewhere so it can be accessed on your search result page, or do the downloading/deserialising there.
You should be able to use the JsonConvert.SerializeObject as detailed below :-
http://james.newtonking.com/projects/json/help/SerializingJSON.html
Related
I want to access a webpage & store the contents of the webpage into a database
this is the code I have tried for reading the contents of the webpage
public static WebClient wClient = new WebClient();
public static TextWriter textWriter;
public static String readFromLink()
{
string url = "http://www.ncedc.org/cgi-bin/catalog-search2.pl";
HttpWebRequest webRequest = WebRequest.Create(url) as HttpWebRequest;
webRequest.Method = "POST";
System.Net.WebClient client = new System.Net.WebClient();
byte[] data = client.DownloadData(url);
string html = System.Text.Encoding.UTF8.GetString(data);
return html;
}
public static bool WriteTextFile(String fileName, String t)
{
try
{
textWriter = new StreamWriter(fileName);
}
catch (Exception)
{
return false;
Console.WriteLine("Data Save Unsuccessful: Could Not create File");
}
try
{
textWriter.WriteLine(t);
}
catch (Exception)
{
return false;
Console.WriteLine("Data Save UnSuccessful: Could Not Save Data");
}
textWriter.Close();
return true;
Console.WriteLine("Data Save Successful");
}
static void Main(string[] args)
{
String saveFile = "E:/test.txt";
String reSultString = readFromLink();
WriteTextFile(saveFile, reSultString);
Console.ReadKey();
}
but this code gives me an o/p as- This script should be referenced with a METHOD of POST. REQUEST_METHOD=GET
please tell me how to resolve this
You are mixing HttpWebRequest with System.Net.WebClient code. They are a different. You can use WebClient.UploadValues to send a POST with WebClient. You will also need to provide some POST data:
System.Net.WebClient client = new System.Net.WebClient();
NameValueCollection postData = new NameValueCollection();
postData.Add("format","ncread");
postData.Add("mintime","2002/01/01,00:00:00");
postData.Add("minmag","3.0");
postData.Add("etype","E");
postData.Add("outputloc","web");
postData.Add("searchlimit","100000");
byte[] data = client.UploadValues(url, "POST", postData);
string html = System.Text.Encoding.UTF8.GetString(data);
You can find out what parameters to pass by inspecting the POST message in Fiddler. And yes, as commented by #Chris Pitman, use File.WriteAllText(path, html);
I'm not sure if it's a fault on your side as I get the same message just by opening the page. The page source does not contain any html so I don't think you can do webRequest.Method = "POST". Have you spoken to the administrators of the site?
The .NET framework provides a rich set of methods to access data stored on the web. First you will have to include the right namespaces:
using System.Text;
using System.Net;
using System.IO;
The HttpWebRequest object allows us to create a request to the URL, and the WebResponse allows us to read the response to the request.
We’ll use a StreamReader object to read the response into a string variable.
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(URL);
myRequest.Method = "GET";
WebResponse myResponse = myRequest.GetResponse();
StreamReader sr = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8);
string result = sr.ReadToEnd();
sr.Close();
myResponse.Close();
In this code sample, the URL variable should contain the URL that you want to get, and the result variable will contain the contents of the web page. You may want to add some error handling as well for a real application.
As far as I see, the URL you're requesting is a perl script. I think it demands POST to get search arguments and therefore delivers search results.
How can I use await with HttpWebRequest in Windows Phone 8 ?
Is there a way to make the IAsyncResult stuff work with await?
private async Task<int> GetCurrentTemperature()
{
GeoCoordinate location = GetLocation();
string url = "http://free.worldweatheronline.com/feed/weather.ashx?q=";
url += location.Latitude.ToString();
url += ",";
url += location.Longitude.ToString();
url += "&format=json&num_of_days=1&key=MYKEY";
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "POST";
webRequest.BeginGetResponse(new AsyncCallback(OnGotWebRequest), webRequest);
}
private void OnGotWebRequest(IAsyncResult asyncResult)
{
HttpWebRequest webRequest = (HttpWebRequest)asyncResult.AsyncState;
var httpResponse = (HttpWebResponse)webRequest.EndGetResponse(asyncResult);
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
string responseText = streamReader.ReadToEnd();
}
}
Thanks!
Use TaskFactory.FromAsync to create a Task<Stream> from the BeginGetRequestStream/EndGetRequestStream methods. Then you can get rid of your OnGotWebRequest completely, and do the same thing for the response.
Note that currently you're calling EndGetResponse when a BeginGetRequestStream call completes, which is inappropriate to start with - you've got to call the EndFoo method to match the BeginFoo you originally called. Did you mean to call BeginGetResponse?
If you install the Microsoft.Bcl.Async package, you get a few async-ready extension methods, including ones for HttpWebRequest.
I am a beginner in WP7. I need to send a request to the server. The request included username, password and an authentication header. If succeeded I get some data from the server in xml form. How can I send the request to the server?
You certainly shouldn't be using the WebClient class as this executes on the UI thread so will cause the app to lock, instead look at the HttpWebRequest class.
There is a good example here: http://www.codeproject.com/Articles/156610/WP7-WebClient-vs-HttpWebRequest
To add headers, you can access the HttpWebRequest.Headers property so you could add a basic authorization header as per this http://devproj20.blogspot.com/2008/02/assigning-basic-authorization-http.html
Alternatively, you can use the HttpWebRequest.Credentials property (see http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.credentials.aspx for more details)
You'd want to check the status code of the response to verify if the authentication was successful, so you'd access the HttpWebResponse.StatusCode property and see if if it is 401 (unauthorized).
Try this one:
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += (s, e) =>
{
string xml = e.Result;
};
webClient.DownloadStringAsync(new Uri("http://..." + your params));
void SendRequest()
{
WebClient wc = new WebClient();
wc.DownloadStringAsync(new Uri("http://somesite.com/webservice"));
wc.DownloadStringCompleted +=DownloadStringCompleted;
}
void DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
Debug.WriteLine("Web service says: " + e.Result);
}
I created a simple SL 4 app to connect to Google Analytics but I keep getting the following exception:
{System.Security.SecurityException: Security error.
at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at GoogleAnalytics.Silverlight.MainPage.<>c__DisplayClass4.<GetResponseCallback>b__3()}
I think it has something to do with xss but I'm not sure how to get around that. The following code works fine in a console app but doesn't in SL.
The UI has a textblock control, here's the code:
private byte[] _data;
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
string requestData = "Email=email#gmail.com" +
"&Passwd=password" +
"&source=Test-App" +
"&accountType=GOOGLE" +
"&service=analytics";
_data = Encoding.UTF8.GetBytes(requestData);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri("https://www.google.com/accounts/ClientLogin", UriKind.Absolute));
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = _data.Length;
request.BeginGetRequestStream(GetRequestStreamCallback, request);
}
private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
this.Dispatcher.BeginInvoke(() =>
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
Stream stream = request.EndGetRequestStream(asynchronousResult);
stream.Write(_data, 0, _data.Length);
stream.Close();
request.BeginGetResponse(GetResponseCallback, request);
}
catch (Exception e)
{
textBlock.Text = e.ToString();
}
});
}
private void GetResponseCallback(IAsyncResult asynchronousResult)
{
this.Dispatcher.BeginInvoke(() =>
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream stream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
textBlock.Text = streamReader.ReadToEnd().Split(new string[] { "Auth=" }, StringSplitOptions.None)[1];
streamReader.Close();
response.Close();
}
catch (Exception e)
{
textBlock.Text = e.ToString();
}
});
}
Update: fixed a typo.
Thanks
Just some tipps, i haven't tested your code yet, but they might help.
Use a WebClient for Web requests, it's much less and cleaner code... You will find examples on MSDN <- this link also contains almost all interesting topics on Silverlight Web/http/https requests and security - a must read in your scenario
Problems might occur if you're testing from a wrong environment like testing the Silverlight object from a local file url (web Url starting with file:///...). Create a Web-Project in your service, configure the Silverlight Project to run in that created Web project under the Test Web Server or the local IIS
I know, no code examples just links or tipps, they might help you though.
Best regards
UPDATE
What exactly are you trying to do? If you want to track, I've seen a few ready solutions for silverlight, for example Silverlight Analytics or Tracking Silverlight. Here is another known solution.
Silverlight cannot connect to GA services, I either have to use a service or JavaScript then pass the data to Silverlight.
I have been using the following code to obtain a simple web response from Apache 2.2 in SilverLight to no avail.
private void bDoIt_Click(object sender, RoutedEventArgs e)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri("/silverlight/TestPage2.html"));
request.Method = "POST";
request.ContentType = "text/xml";
request.BeginGetRequestStream(new AsyncCallback(RequestProceed), request);
}
private void RequestProceed(IAsyncResult asuncResult)
{
HttpWebRequest request = (HttpWebRequest)asuncResult.AsyncState;
StreamWriter postDataWriter = new StreamWriter(request.EndGetRequestStream(asuncResult));
postDataWriter.Close();
request.BeginGetResponse(new AsyncCallback(ResponceProceed), request);
}
private void ResponceProceed(IAsyncResult asuncResult)
{
HttpWebRequest request = (HttpWebRequest)asuncResult.AsyncState;
HttpWebResponse responce = (HttpWebResponse)request.EndGetResponse(asuncResult);
StreamReader responceReader = new StreamReader(responce.GetResponseStream());
string responceString = responceReader.ReadToEnd();
txtData.Text = responceString;
}
Does anyone no a better method of doing this?
Have you tried WebClient? This exists on silverlight, and might make life easier. Presumably you'd want UploadStringAsync.
Also - I believe you need to use and absolute url; if you don't want to hard code (quite reasonably), you can get your host from:
string url = App.Current.Host.Source.AbsoluteUri;
Then use string / etc methods to make the correct "http://yoursite/whatever/your.page";
Note that silverlight only allows (IIRC) connections to the host site.
You can do the BeginGetResponse call as the first call in your sample test case, the BeginGetRequestStream call is only needed if you are intending to pass some POST data to the requested page.