I'm making an HTTP call. My response contains a session code X-BB-SESSION in the header section of the HttpResponseMessage object. How do I get that specific header value?
I am using a foreach statement to iterate through all the headers (MSDN link). However the compiler keeps saying that it cannot be done:
foreach statement cannot operate on variables of type
System.net.http.headers.cachecontrolheadervalue because
'System.net.http.headers.cachecontrolheadervalue' doesn't contain
a public definition for 'GetEnumerator'
This is the code I'm trying:
//Connection code to BaasBox
HttpResponseMessage response = await client.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead);
if (response.IsSuccessStatusCode)
{
//get the headers
HttpResponseHeaders responseHeadersCollection = response.Headers;
foreach (var value in responseHeadersCollection.CacheControl) --> HERE
{
string sTemp = String.Format("CacheControl {0}={1}", value.Name, value.Value);
} else
{
Console.WriteLine("X-BB-SESSION: NOT Found");
}
The header content from where I'm trying to get the value (X-BB-SESSION value) is something like:
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With
X-BB-SESSION: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
You should be able to use the TryGetValues method.
HttpHeaders headers = response.Headers;
IEnumerable<string> values;
if (headers.TryGetValues("X-BB-SESSION", out values))
{
string session = values.First();
}
Using Linq aswell, this is how I solved it.
string operationLocation = response.Headers.GetValues("Operation-Location").FirstOrDefault();
I think it's clean and not too long.
Though Sam's answer is correct. It can be somewhat simplified, and avoid the unneeded variable.
IEnumerable<string> values;
string session = string.Empty;
if (response.Headers.TryGetValues("X-BB-SESSION", out values))
{
session = values.FirstOrDefault();
}
Or, using a single statement with a ternary operator (as commented by #SergeySlepov):
string session = response.Headers.TryGetValues("X-BB-SESSION", out var values) ? values.FirstOrDefault() : null;
If someone like method-based queries then you can try:
var responseValue = response.Headers.FirstOrDefault(i=>i.Key=="X-BB-SESSION").Value.FirstOrDefault();
You are trying to enumerate one header (CacheControl) instead of all the headers, which is strange. To see all the headers, use
foreach (var value in responseHeadersCollection)
{
Debug.WriteLine("CacheControl {0}={1}", value.Name, value.Value);
}
to get one specific header, convert the Headers to a dictionary and then get then one you want
Debug.WriteLine(response.Headers.ToDictionary(l=>l.Key,k=>k.Value)["X-BB-SESSION"]);
This will throw an exception if the header is not in the dictionary so you better check it using ContainsKey first
Below Code Block Gives A formatted view of Response Headers
WebRequest request = WebRequest.Create("https://-------.com");
WebResponse response = request.GetResponse();
foreach (var headerItem in response.Headers)
{
IEnumerable<string> values;
string HeaderItemValue="";
values = response.Headers.GetValues(headerItem.ToString());
foreach (var valueItem in values)
{
HeaderItemValue = HeaderItemValue + valueItem + ";";
}
Console.WriteLine(headerItem + " : " + HeaderItemValue);
}
Related
I am coming to a problem where I have a guid style schema in my firebase database, which I want to display a text that is DisplayText, but for some reason my code is not working. I am using a FirebaseDatabase.Net Wrapper. How can I map it in order to read from the database properly using a guid way schema? thanks for the help.
Code:
private async Task ShowQuestion()
{
var firebase = new
FirebaseClient("https://PROJECT_URL.firebaseio.com/");
var dinos = await firebase
.Child("Questions")
.OrderByKey()
.StartAt("DisplayText")
.LimitToFirst(1)
.OnceAsync<GameController>();
foreach (var dino in dinos)
{
Console.WriteLine(dinos);
}
I tried doing:
string page = "https://PROJECT_URL.firebaseio.com/Questions/DisplayText.json?orderBy"DisplayText"&limitToFirst=1";
using (HttpClient client = new HttpClient())
using (HttpResponseMessage response = await client.GetAsync(page))
using (HttpContent content = response.Content)
{
// Reading the string.
string result = await content.ReadAsStringAsync();
Console.WriteLine(result);
// Getting a reference to the text component.
questionDisplayText = GetComponent<Text>();
questionDisplayText.text = result.ToString();
questionDisplayText.text = result.Trim(new char[] {'"'});
}
Firebase queries take a two-step approach:
You order the child nodes on their key, their value, or the value of a property.
You then filter on values of the thing you ordered on.
Since you order by key, the filtering operations like StartAt() compare the key to the value you passed. And since there is no key DisplayText, there are no results.
If you want to read the first question, you shouldn't use a startAt().
FirebaseClient("https://PROJECT_URL.firebaseio.com/");
var dinos = await firebase
.Child("Questions")
.OrderByKey()
.LimitToFirst(1)
If you want to return the results ordered by the value of their DisplayText property, it'd be something like this:
FirebaseClient("https://PROJECT_URL.firebaseio.com/");
var dinos = await firebase
.Child("Questions")
.OrderByChild("DisplayText")
.LimitToFirst(1)
Since you indicated that you want to use the REST API, here's an example of how to do that:
https://stackoverflow.firebaseio.com/59384124.json?orderBy="DisplayText"&startAt="How"
If you want to embed this string in your code, you have a few options. The main ones:
string page = "https://PROJECT_URL.firebaseio.com/Questions/DisplayText.json?orderBy=\"DisplayText\"&startAt=\"How\"&limitToFirst=1";
Or
string page = #"https://PROJECT_URL.firebaseio.com/Questions/DisplayText.json?orderBy=""DisplayText""&startAt=""How""&limitToFirst=1";
And don't forget: in order to be able to filter on the server, you'll need to define an index in your security rules. In my case I did so with:
"59384124": { ".indexOn": "DisplayText" },
Also see:
The documentation for the Firebase REST API
This blog post on embedding quotes in C# strings
I'm trying to get an object List from cors API but all of the List entries are null.
I succeeded in obtaining the List (list type and length are ok).
List<PluginModelDB> result;
using (HttpResponseMessage response = await ApiBroker.ApiClient.GetAsync(""))
{
if (response.IsSuccessStatusCode)
{
result = await response.Content.ReadAsAsync<List<PluginModelDB>>();
}
else
{
throw new Exception(response.ReasonPhrase);
}
}
HomeViewModel.PluginList = new List<PluginModelDB>();
foreach (var p in result)
{
HomeViewModel.PluginList.Add(new PluginModelDB { ID = p.ID, Name = p.Name, Description = p.Description});
}
Try to read it as string first, so don't deserialize it immediately. Output that string to Console or a simple text file and see if you can track you items there. If not, the problem is at the API, its returning empty objects.
It seems that your model is not corresponds to received JSON. You can check you model via http://json2csharp.com/
I have a program that comunicates with an external http server to the request a first, second etc value... (1º,2º,3º,4º,...)
I have an issue in c# with the º character.
Here is some example code:
var testdata=new Dictionary<string,string>{
{"val","º"},
{"val1","\xBA"},
{"val2","\u00BA"},
};
var content = new FormUrlEncodedContent(testdata);
var cont = content.ReadAsStringAsync().GetAwaiter().GetResult();
the result is:
val=%C2%BA&val1=%C2%BA&val2=%C2%BA
I test the communication with the server with curl and firefox console
and the result should be:
val=%BA&val1=%BA&val2=%BA
Somehow the extra %C2 in C# dosent work with the server.
How can I fix or escape the º correctly?
This issue relates with the default encoding used by FormUrlEncodedContent which is UTF-8 and your server expect ISO-8859-1.
Here is a workaround to get over it but you'll need (unfortunately) to add System.Web to your project :
// This is an implementation of FormUrlEncodedContent with `ISO-8859-1`
public class FormIso8859Encoder : ByteArrayContent
{
public FormIso8859Encoder(IEnumerable<KeyValuePair<string, string>> nameValueCollection)
: base(FormDataToByteArray(nameValueCollection))
{
Headers.Add("Content-Type", "application/x-www-form-urlencoded");
}
private static byte[] FormDataToByteArray(IEnumerable<KeyValuePair<string, string>> nameValueCollection)
{
StringBuilder sb = new StringBuilder();
foreach (var nameValue in nameValueCollection)
{
if (sb.Length > 0)
sb.Append('&');
sb.Append(nameValue.Key);
sb.Append('=');
// Here is the major change
sb.Append(HttpUtility.UrlEncode(nameValue.Value, Encoding.GetEncoding("iso-8859-1") ));
}
return Encoding.Default.GetBytes(sb.ToString());
}
}
Then
var testdata=new Dictionary<string,string>{
{"val","º"},
{"val1","\xBA"},
{"val2","\u00BA"},
};
var content = new FormIso8859Encoder(testdata);
var cont = content.ReadAsStringAsync().GetAwaiter().GetResult();
This provide the following output :
val=%BA&val1=%BA&val2=%BA
The correct unicode character for ° is \u00B0. More info can you find here how to work with unicode in C#.
All unicode characters can be found here.
Hello I would determine a method to input any kind of location data (I can cater it to just about anything) such as a city/state, a zip code, a street address etc. And get back the local time for that location.
Is that functionality build in somewhere or is there a good resource/class I can use already developed?
Thanks.
Ended up retrieving the search result from a Google search, since I did not have the lat/long.
User HTML Agility to extract the page contents, filtered the nodes that contained "Time", a simple enough the first item was the needed result.
If you google "time cincinnati oh" you get back "1:41pm Friday (EDT) - Time in Cincinnati, OH" at the top of the page. this code block extracts that. The safety is if the time is unable to be determined, the search page only shows the results, so the first item in the array is like, "Showing the results for "yourSearch"" etc.
public void timeZoneUpdate()
{
try
{
arrayToParse.Clear();
string URL = #"https://www.google.com/search?q=time+" + rowCity + "%2C+" + rowState;
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();
//Console.Write(result);
HtmlAgilityPack.HtmlDocument htmlSnippet = new HtmlAgilityPack.HtmlDocument();
htmlSnippet.Load(new StringReader(result));
bool foundSection = false;
foreach (HtmlAgilityPack.HtmlNode table in htmlSnippet.DocumentNode.SelectNodes("//table"))
{
foreach (HtmlAgilityPack.HtmlNode row in table.SelectNodes("tr"))
{
foreach (HtmlAgilityPack.HtmlNode cell in row.SelectNodes("td"))
{
if (cell.InnerText.Contains("Time"))
{
foundSection = true;
}
if (foundSection)
{
//Console.WriteLine("Cell value : " + cell.InnerText);
arrayToParse.Add(cell.InnerText);
}
}
}
}
retrievedTimeZone = arrayToParse[0].ToString().Split('-')[0].Trim();
if(retrievedTimeZone.Contains("Showing"))
{
retrievedTimeZone = "Undetermined";
}
}
I have to really ask this question as I donot know Python.
Following are a few lines taken from this place. I would appreciate if someone guides me in translating the following to C#
#Step 1: Get a session key
servercontent = myhttp.request(baseurl + '/services/auth/login', 'POST',
headers={}, body=urllib.urlencode({'username':username, 'password':password}))[1]
sessionkey = minidom.parseString(servercontent).getElementsByTagName('sessionKey')[0].childNodes[0].nodeValue
print "====>sessionkey: %s <====" % sessionkey
I can't translate it to C#, but I can explain what this code does:
Login to baseurl + '/services/auth/login' using the username and password provided.
Read the contents of that URL.
Parse the content for the first <sessionkey> tag, and read the value of its first child node.
Here's a quick-n-dirty translation:
using System.Linq.Xml;
using System.Net;
using System.Collections.Generic;
using System.Web;
// ...
var client = new WebClient();
var parameters = new Dictionary<string, string>
{
{ "username", username },
{ "password", password }
};
var result = client.UploadString(String.Format("{0}/services/auth/login", BaseUrl), UrlEncode(parameters));
var doc = XDocument.Load(result); // load response into XML document (LINQ)
var key = doc.Elements("sessionKey").Single().Value // get the one-and-only <sessionKey> element.
Console.WriteLine("====>sessionkey: {0} <====", key);
// ...
// Utility function:
private static string UrlEncode(IDictionary<string, string> parameters)
{
var sb = new StringBuilder();
foreach(var val in parameters)
{
// add each parameter to the query string, url-encoding the value.
sb.AppendFormat("{0}={1}&", val.Key, HttpUtility.UrlEncode(val.Value));
}
sb.Remove(sb.Length - 1, 1); // remove last '&'
return sb.ToString();
}
This code does a check to see that the response only has one sessionKey element, otherwise it'll throw an exception if there's 0, or more than 1. Then it prints it out.