Visit a URL with a variable altering the url, windows phone - windows-phone-7

I have a URL that is shown below:
URL is taken out due to contract reasons
WebClient webClient = new WebClient();
Uri uri = new Uri("http://www.URLhere.aspx?stopid=4556");
webClient.OpenReadCompleted += new OpenReadCompletedEventHandler
(webClient_OpenReadCompleted);
webClient.OpenReadAsync(uri);
I need to find a way to alter the end part, so change 4556 from a text block, into another text so that when the application send the request it finds the whole lot.
I thought you could do this:
WebClient webClient = new WebClient();
Uri uri = new Uri("http://www.URLhere.aspx?stopid=" + stopId);
webClient.OpenReadCompleted += new OpenReadCompletedEventHandler
(webClient_OpenReadCompleted);
webClient.OpenReadAsync(uri);
How does one do this?
Edit:
When i do the code above it returns as a null reference, so i am asuming it's not getting the text in the textbox.

It sounds like you're missing the encoding of your variable.
var myvar = "the simpsons";
Uri myUri = new Uri("http://www.URLhere.aspx?stopid=" + HttpUtility.UrlEncode(myvar));
See HttpUtility.UrlEncode Method - MSDN

there is no difference between
Uri uri = new Uri("http://www.URLhere.aspx?stopid=4556");
and
Uri uri = new Uri("http://www.URLhere.aspx?stopid=" + stopId);
so i really don't know whats your problem

Henry,
If I understand you question correctly, I think you want to append the value in a TextBox (not a TextBlock) to the URI. If that is correct and you're employing MVVM, you could bind your TextBox to a public property on the ViewModel (lets call it TextBoxProp)
private string _textBoxProp;
public string TextBoxProp
{
get{return _textBoxProp;}
set
{
_textBoxProp = value;
RaisePropertyChanged("TextBoxProp");
}
}
and then create your URI as follows:
Uri uri = new Uri(String.Format("http://www.URLhere.aspx?stopid={0}", TextBoxProp));
Be sure when you bind to the property in XAML that you set the mode to TwoWay.
I hope that helps

Related

AndroidClientHandler and built-in Basic authentication

I'm trying to make the built-in Basic Authentication work with the Xamarin AndroidClientHandler, but with no success. The code looks like this:
https://github.com/tieto-sternell/DemoAndroidBasicAuth/blob/c6bb4d547f2456e66b25daca4951957250278ac3/DemoAndroidBasicAuth/DemoAndroidBasicAuth.Droid/TestStuff.cs#L39-L43
ICredentials credentials = new NetworkCredential(dummyUsername, dummyPassword);
var handler = new AndroidClientHandler();
handler.Credentials = credentials;
and:
https://github.com/tieto-sternell/DemoAndroidBasicAuth/blob/c6bb4d547f2456e66b25daca4951957250278ac3/DemoAndroidBasicAuth/DemoAndroidBasicAuth.Droid/TestStuff.cs#L19-L21
var client = new HttpClient(handler);
var badResponse = await client.GetAsync(basicUri) as AndroidHttpResponseMessage;
As you can see, it is pretty straight-forward and the code looks very similar to its working .Net equivalent. The response is 401, though, so I am doing something wrong.
Edit: As #jgoldberger points out below, it is possible to create the headers manually. This can be done either by adding a header to the message (github.com/tieto-sternell/DemoAndroidBasicAuth/blob/e7118f88a5b45f91207e90e9ea64c554d0ea9cd6/DemoAndroidBasicAuth/DemoAndroidBasicAuth.Droid/TestStuff.cs#L43-L48)
byte[] byteToken = System.Text.Encoding.UTF8.GetBytes(dummyUsername + ":" + dummyPassword);
var tokenValue = Convert.ToBase64String(byteToken);
var token = "Basic " + tokenValue;
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri(basicUri));
requestMessage.Headers.Add("Authorization", token.ToString());
Or by adding a header to the HttpClient (github.com/tieto-sternell/DemoAndroidBasicAuth/blob/e7118f88a5b45f91207e90e9ea64c554d0ea9cd6/DemoAndroidBasicAuth/DemoAndroidBasicAuth.Droid/TestStuff.cs#L33-L37)
byte[] byteToken = System.Text.Encoding.UTF8.GetBytes(dummyUsername + ":" + dummyPassword);
var tokenValue = Convert.ToBase64String(byteToken);
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", tokenValue);
I don't think that this is how it is supposed to work, though. I mean, when is this (github.com/xamarin/xamarin-android/blob/0c3597869bc4493895e755bda8a26f778e4fe9e0/src/Mono.Android/Xamarin.Android.Net/AuthModuleBasic.cs#L50-L52)
response += cred.UserName + ":" + cred.Password;
return new Authorization ($"{AuthenticationType} {Convert.ToBase64String (Encoding.ASCII.GetBytes (response))}");
code supposed to run in that case?
It looks to me as if the Authentication module isn't used.
The background story here is that I need to know how to make Basic work as part of a larger problem which involves Digest authentication and the custom "AuthenticationScheme.Unsupported", but we'll get there later when we've got the simpler basic auth scheme up and running.
Best regards,
Christian

Globally formatting .net Web Api response

I have a Web Api service that retrieves data from another service, which returns Json. I don't want to do anything to the response, I just want to return it directly to the client.
Since the response is a string, if I simply return the response, it contains escape characters and messy formatting. If I convert the response in to an object, the WebApi will use Json.Net to automatically format the response correctly.
public IHttpActionResult GetServices()
{
var data = _dataService.Get(); //retrieves data from a service
var result = JsonConvert.DeserializeObject(data); //convert to object
return Ok(result);
}
What I would like is to either A: Be able to return the exact string response from the service, without any of the escape characters and with the proper formatting, or B: Set a global settings that will automatically Deserialize the response so that the Web Api can handle it the way I am doing it already.
On Startup I am setting some values that describe how formatting should be handled, but apparently these aren't correct for what im trying to do.
HttpConfiguration configuration = new HttpConfiguration();
var settings = configuration.Formatters.JsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new DefaultContractResolver();
Do I need to create a custom ContractResolver or something? Is there one that already handles this for me?
Thanks
If you want to just pass through the json (Option A), you can do this
public IHttpActionResult GetServices() {
var json = _dataService.Get(); //retrieves data from a service
HttpContent content = new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json");
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = content;
return ResponseMessage(response);
}

How to retrieve message from WEB API?

I created some web apis and when an error happens the api returns HttpResponseMessage that is created with CreateErrorResponse message. Something like this:
return Request.CreateErrorResponse(
HttpStatusCode.NotFound, "Failed to find customer.");
My problem is that I cannot figure out how to retrieve the message (in this case "Failed to find customer.") in consumer application.
Here's a sample of the consumer:
private static void GetCustomer()
{
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
string data =
"{\"LastName\": \"Test\", \"FirstName\": \"Test\"";
var content = new StringContent(data, Encoding.UTF8, "application/json");
var httpResponseMessage =
client.PostAsync(
new Uri("http://localhost:55202/api/Customer/Find"),
content).Result;
if (httpResponseMessage.IsSuccessStatusCode)
{
var cust = httpResponseMessage.Content.
ReadAsAsync<IEnumerable<CustomerMobil>>().Result;
}
}
Any help is greatly appreciated.
Make sure you set the accept and or content type appropriately (possible source of 500 errors on parsing the request content):
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/json");
Then you could just do:
var errorMessage = response.Content.ReadAsStringAsync().Result;
That's all on the client of course. WebApi should handle the formatting of the content appropriately based on the accept and/or content type. Curious, you might also be able to throw new HttpResponseException("Failed to find customer.", HttpStatusCode.NotFound);
One way to get the message is to do:
((ObjectContent)httpResponseMessage.Content).Value
This will give you a dictionary that contains also the Message.
UPDATE
Refer to the official page:
http://msdn.microsoft.com/en-us/library/jj127065(v=vs.108).aspx
You have to vary the way you're reading the successful response and the error response as one is obviously in your case StreamContent, and the other should be ObjectContent.
UPDATE 2
Have you tried doing it this way ?
if (httpResponseMessage.IsSuccessStatusCode)
{
var cust = httpResponseMessage.Content.
ReadAsAsync<IEnumerable<CustomerMobil>>().Result;
}
else
{
var content = httpResponseMessage.Content as ObjectContent;
if (content != null)
{
// do something with the content
var error = content.Value;
}
else
{
Console.WriteLine("content was of type ", (httpResponseMessage.Content).GetType());
}
}
FINAL UPDATE (hopefully...)
OK, now I understand it - just try doing this instead:
httpResponseMessage.Content.ReadAsAsync<HttpError>().Result;
This is an option to get the message from the error response that avoids making an ...Async().Result() type of call.
((HttpError)((ObjectContent<HttpError>)response.Content).Value).Message
You should make sure that response.Content is of type ObjectContent<HttpError> first though.
It should be in HttpResponseMessage.ReasonPhrase. If that sounds like a bit of a strange name, it's just because that is the way it is named in the HTTP specification http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html
OK this is hilarious, but using QuickWatch I came up with this elegant solution:
(new System.Collections.Generic.Mscorlib_DictionaryDebugView(((System.Web.Http.HttpError)(((System.Net.Http.ObjectContent)(httpResponseMessage.Content)).Value)))).Items[0].Value
That is super readable!

How to pull the finalUri property from an async image lookup result?

In windows phone 7 I'm doing a simple async lookup to find an image by uri and set the returned binary as the source for an image control.
public object SetImageFromUri(string uri)
{
var wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(new Uri(uri), wc);
return null;
}
void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null && !e.Cancelled)
{
var image = new BitmapImage();
image.SetSource(e.Result);
//e.Result has a property in the memory stream labeled finalUri
//someImageControl.Source = image;
}
}
My question is- how can I pull out the final uri property from the e.Result so I can see what image control it's associated with
Thank you in advance
Instead of passing the WebClient through as the second parameter, pass the Uri (or some other piece of usefule state information)
wc.OpenReadAsync(new Uri(uri), uri);
You can then access this in your callback
var uri = (string)e.UserState;
Due to specific restrictions implemented in the Reflection mechanism, you cannot access internal content from sandboxed code. Ultimately, you would want to use something like this:
FieldInfo f = e.Result.GetType().GetField("_finalUri", BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance);
Uri n = (Uri)f.GetValue(e.Result);
However, this will cause a FieldAccessException. If you are not using a redirect URI, then you can simply reuse the parameter that is initially passed to your method. If not, you need to check HttpWebRequest and follow the idea I outlined a couple of days ago.
You could also just bind directly to the Image, and use the LowProfileImageLoader, to avoid it blocking the UI thread during the load. (Remember to set a FallBack image)

WebClient NotFound error but working with HttpWebRequest/Response

In my WinPhone app I'm accessing a REST service.
At the beginnings I was using this code:
WebClient wc = new WebClient();
wc.Credentials = credentials;
wc.Headers["App-Key"] = appKey;
wc.DownloadStringCompleted +=
(o, args) => MessageBox.Show(args.Error == null ? "OK" : "Error");
wc.DownloadStringAsync(uri);
but it suddenly stopped working returning me a "The remote server returned an error: NotFound" error. After a google session and some clicks in the control panel, I didn't get it to work.
I decided to try this other way:
HttpWebRequest request = HttpWebRequest.CreateHttp(uri);
request.Credentials = credentials;
request.Headers["App-Key"] = appKey;
request.BeginGetResponse(asResult =>
{
var response = request.EndGetResponse(asResult) as HttpWebResponse;
StreamReader reader = new StreamReader(response.GetResponseStream());
string responseString = reader.ReadToEnd();
Dispatcher.BeginInvoke(
() => MessageBox.Show(response.StatusCode.ToString()));
}, null);
and it works.
I also tried to run the first snipped pointing the URI to google's home page and it works (I had to remove the credentials, of course).
Can anyone explain what's going on?
UPDATE
I managed to get it working by replacing the
wc.Credentials = new NetworkCredentials(username, password);
with
wc.Headers["Authorization"] = "Basic someBase64encodedString";
but i still wonder what happened and which are the differences between the first and the second line.
PS: the test URI is: https://api.pingdom.com/api/2.0/checks but you will need an app-key from them.
When using the Credentials property, the HttpWebRequest implementation will wait the challenge response from server before to send the 'Authorization' header value.
But this can be an issue in some cases, so you have to force Basic authentication by providing directly the Authorization header.
Example when using a REST Client library like Spring.Rest :
RestTemplate template = new RestTemplate("http://example.com");
template.RequestInterceptors.Add(new BasicSigningRequestInterceptor("login", "password"));
string result = template.GetForObject<string>(uri);

Resources