Cookies are update fine in all browsers but in google chrome, it fails to update the cookies.
Bellow is my code:
public static string CustomerName
{
get { return CookieStore.GetCookie("customername"); }
set { CookieStore.SetCookie("customername", value.ToString(), TimeSpan.FromHours(24), true); }
}
public static void SetCookie(string key, string value, TimeSpan expires, bool http = false)
{
HttpCookie encodedCookie = new HttpCookie(key, value);
// encodedCookie.HttpOnly = http;
if (HttpContext.Current.Request.Cookies[key] != null)
{
var cookieOld = HttpContext.Current.Request.Cookies[key];
cookieOld.Expires = DateTime.Now.Add(expires);
cookieOld.Value = encodedCookie.Value;
HttpContext.Current.Response.Cookies.Add(cookieOld);
}
else
{
encodedCookie.Expires = DateTime.Now.Add(expires);
HttpContext.Current.Response.Cookies.Add(encodedCookie);
}
}
Actually the problem found in SetCookie function. you need to replace the following line of code
var cookieOld = HttpContext.Current.Request.Cookies[key];
with the following line while updating your cookie.
var cookieOld = new HttpCookie(key);
Bellow is the complete SetCookie function.
public static void SetCookie(string key, string value, TimeSpan expires, bool http = false)
{
if (HttpContext.Current.Request.Cookies[key] != null)
{
var cookieOld = new HttpCookie(key);
cookieOld.Expires = DateTime.Now.Add(expires);
cookieOld.Value = value;
HttpContext.Current.Response.Cookies.Add(cookieOld);
}
else
{
HttpCookie encodedCookie = new HttpCookie(key, value);
encodedCookie.Expires = DateTime.Now.Add(expires);
HttpContext.Current.Response.Cookies.Add(encodedCookie);
}
}
Related
So, in the code below, In the last method, I want to re use the second one public static Valute GetValuteByDate(DateTime date, string valuteCharCode), but I really don't understand what parameters to give. As you can see, I successfully re-used first method in the second method. Any idea what I can do to re-use the second method in the third one? Or maybe you have some useful information?
public static class Api
{
public static ValCurs GetValCursByDate(DateTime date)
{
var client = new RestClient("http://bnm.md"); //request
var request = new RestRequest("ro/official_exchange_rates/get_xml=1&date="+date.ToString(), Method.GET); //request
var response = client.Execute<ValCurs>(request);//deserialization
if (response.ErrorException != null) { return null; } //throw exception
return response.Data;
}
public static Valute GetValuteByDate(DateTime date, string valuteCharCode)
{
var curs = GetValCursByDate(date);
Valute valuteByDate = curs.FirstOrDefault(valute => valute.CharCode.Equals(valuteCharCode));
return valuteByDate;
}
public static Valute GetMaxValuteByPeriod(DateTime startDate, DateTime endDate, string charCode)
{
var maxVal = GetValuteByDate(**?**);
}
}
public static class Api
{
public static ValCurs GetValCursByDate(DateTime date)
{
var client = new RestClient("http://bnm.md"); //request
var request = new RestRequest("ro/official_exchange_rates/get_xml=1&date="+date.ToString(), Method.GET); //request
var response = client.Execute<ValCurs>(request);//deserialization
if (response.ErrorException != null) { return null; } //throw exception
return response.Data;
}
public static Valute GetValuteByDate(DateTime date, string valuteCharCode)
{
var curs = GetValCursByDate(date);
Valute valuteByDate = curs.FirstOrDefault(valute => valute.CharCode.Equals(valuteCharCode));
return valuteByDate;
}
public static Valute GetMaxValuteByPeriod(DateTime startDate, DateTime endDate, string charCode)
{
var totalDays = (endDate-startDate).TotalDays;
List<Valute> result = new List<Valute>(totalDays);
for(int i = 0; i < totalDays; i++)
{
result.Add(GetValuteByDate(startDate.AddDays(i), charCode);
}
var maxVal = result.Max(p => p.<put here property>);
return maxVal;
}
}
The third one seems to be using a range, so you'd need to call the second one for each day in the range.
for(var day = startDate; date<= endDate; day = day.AddDays(1))
{
Valute value = GetValuteByDate(date, valuteCharCode);
//compare value to the max value and set if higher
}
Note: I didn't test this code so you might have to fiddle with it
I am creating a new webhook C# function in Azure that I wish to return fixed content in different translations depending on either an incoming lang query parameter or the Accept-Language header.
For storing the different translations I naturally think of .resx files. Is there a way to utilize .resx files in Azure Function Apps?
It doesn't look like resource files are supported properly yet.
I worked around by reading the embedded resource file(s) into a resource set.
var culture = CultureInfo.CurrentUICulture;
var resourceName = $"FunctionApp.Properties.Resources.{culture.TwoLetterISOLanguageName}.resources";
var cultureResourceSet = new ResourceSet(Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName));
var localizedString = cultureResourceSet.GetString(resourceKey);
// fallback to default language if not found
Provided answer did not help me so I've done small wrapper
public static class ResourceWrapper
{
private static Dictionary<string, ResourceSet> _resourceSets = new Dictionary<string, ResourceSet>();
static ResourceWrapper()
{
_resourceSets.Add("uk", Load("uk"));
_resourceSets.Add("ru", Load("ru"));
_resourceSets.Add("en", Emails.ResourceManager.GetResourceSet(CultureInfo.InvariantCulture, false, false));
}
private static ResourceSet Load(string lang)
{
var asm = System.Reflection.Assembly.LoadFrom(Path.Combine(Environment.CurrentDirectory, "bin", lang, "Function.App.resources.dll"));
var resourceName = $"Function.App.Resources.Emails.{lang}.resources";
var tt = asm.GetManifestResourceNames();
return new ResourceSet(asm.GetManifestResourceStream(resourceName));
}
public static string GetString(string key)
{
return _resourceSets[CultureInfo.CurrentUICulture.TwoLetterISOLanguageName].GetString(key);
}
}
this was my solution:
First i do this:
public void SetLanguage(FunctionRequestDTO data)
{
if (string.IsNullOrWhiteSpace(data.LanguageSetting))
{
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
}
else
{
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(data.LanguageSetting);
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(data.LanguageSetting);
}
ResourceWrapper.Load(Thread.CurrentThread.CurrentCulture.Name.ToLower());
}
Then:
public static class ResourceWrapper
{
private static Dictionary<string, ResourceSet> ResourceSets = new Dictionary<string, ResourceSet>();
private const string DEFAULT_LANGUAGE_VALUE = "default";
static ResourceWrapper()
{
try
{
ResourceSets.Add(DEFAULT_LANGUAGE_VALUE, new ResourceSet(Assembly.GetExecutingAssembly().GetManifestResourceStream("Function.Logic.Resources.Resource.resources")));
}
catch { }
}
public static void Load(string lang)
{
if (string.IsNullOrEmpty(lang) || ResourceSets.ContainsKey(lang))
{
return;
}
lock (new object())
{
if (ResourceSets.ContainsKey(lang))
{
return;
}
try
{
string rootPath = Environment.CurrentDirectory;
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("HOME")))
{
rootPath = Environment.GetEnvironmentVariable("HOME") + "\\site\\wwwroot\\";
}
var asm = Assembly.LoadFrom(Path.Combine(rootPath, "bin", lang, "Function.Logic.resources.dll"));
var resourceName = $"Function.Logic.Resources.Resource.{lang}.resources";
ResourceSets.Add(lang, new ResourceSet(asm.GetManifestResourceStream(resourceName)));
}
catch { }
}
}
public static string GetString(string key)
{
string value = "";
try
{
string language = System.Threading.Thread.CurrentThread.CurrentCulture.Name.ToLower();
if (string.IsNullOrEmpty(language))
{
language = DEFAULT_LANGUAGE_VALUE;
}
if (ResourceSets.ContainsKey(language))
{
value = ResourceSets[language].GetString(key);
}
}
catch { }
return value ?? "";
}
I used to work with browser-based applications. for example Angular simple repository.
function getSomeData(params) {
...
return $http({
url: conf.urlDev + 'some/rest-url',
method: "GET",
params: params,
cache: true
}).then(getDataComplete);
function getDataComplete(response) {
return response.data;
}
}
How it will look the same in c# (XAMARIN for example)?
i try :
public class BaseClient
{
protected Http _client = null;
protected string _urlObj;
protected string _basePath;
public BaseClient ()
{
_client = new Http(new HttpClientHandler());
}
public string Path
{
set
{
_urlObj = value;
}
}
public async Task<Result<IList<T>>>getList<T>(Dictionary<string,object> parametrs = null)
{
if (parametrs != null)
{
foreach(KeyValuePair<string, object> keyValue in parametrs)
{
_urlObj = _urlObj.SetQueryParam(keyValue.Key, keyValue.Value);
}
}
var response = await _client.GetAsync(_urlObj.ToString());
if (response.IsSuccessStatusCode)
{
return new Result<IList<T>>()
{
Success = true,
Value = JsonConvert.DeserializeObject<IList<T>>(await response.Content.ReadAsStringAsync())
};
}
else
{
var error = new Result<IList<T>>()
{
Error = response.StatusCode.ToString(),
Message = response.ReasonPhrase,
Success = false
};
return error;
}
}
in my service:
public async Task<IList<News>> GetAllNewsByParams(DateTime from,
string orderBy = "-published",
DateTime to = new DateTime(),
int page = 1, int category = 0)
{
_client.Path = _config.NewsPath;
var dict = new Dictionary<string, object> {
{"from", from.ToString("s")},
{"order_by", orderBy.ToString()},
{"to", to.ToString("s")},
{"page", page.ToString()}
};
if (category != 0)
{
dict.Add("category", category.ToString());
}
var res = await _client.getList<News>(dict);
return res.Value;
}
and im ny viewmodel
foreach (var item in await _newsService.GetAllNewsByParams(
_To,
_OrderBy,
_From, _Page,
selectedTag == null ? _SeletedNewsTagId : selectedTag.Id))
{
NewsList.Add(item);
}
Is his query executed synchronously ?
How do I make it an asynchronous?
First of all I would really encourage you to use RestSharp, it really simplifies making HTTP requests and deserialise them. Add a RestSharp nuget package to your project. Here is how your code will look like using RestSharp.
public class BaseClient
{
protected IRestClient _client = null;
protected string _urlObj;
protected string _basePath;
public BaseClient()
{
_client = new RestClient();
}
public async Task<Result<IList<T>>> GetList<T>(string path, Dictionary<string, object> parametrs = null)
{
var request = new RestRequest(path, Method.GET);
if (parametrs != null)
{
foreach (var keyValue in parametrs)
{
request.AddQueryParameter(keyValue.Key, keyValue.Value);
}
}
var response = await _client.Execute<List<T>>(request);
if (response.IsSuccess)
{
return new Result<IList<T>>()
{
Success = true,
Value = response.Data
};
}
else
{
var error = new Result<IList<T>>()
{
Error = response.StatusCode.ToString(),
Message = response.StatusDescription,
Success = false
};
return error;
}
}
}
In your service
public async Task<IList<News>> GetAllNewsByParams(DateTime from,
string orderBy = "-published",
DateTime to = new DateTime(),
int page = 1, int category = 0)
{
var dict = new Dictionary<string, object> {
{"from", from.ToString("s")},
{"order_by", orderBy.ToString()},
{"to", to.ToString("s")},
{"page", page.ToString()}
};
if (category != 0)
{
dict.Add("category", category.ToString());
}
var res = await _client.GetList<News>(_config.NewsPath, dict);
return res.Value;
}
And in your viewmodel
var news = await _newsService.GetAllNewsByParams(
_To,
_OrderBy,
_From, _Page,
selectedTag == null ? _SeletedNewsTagId : selectedTag.Id);
foreach (var item in news)
{
NewsList.Add(item);
}
This will be 100% asynchronous.
I am trying to set an arbitrary path in a JSON structure and I am having difficulty figuring out how to do a simple set value...
What I would like is some method like, SetValue(path,value) which operates like SelectToken, but creates the path if it does not exist and sets the value.
public void SetPreference(string username, string path, string value)
{
var prefs = GetPreferences(username);
var jprefs = JObject.Parse(prefs ?? #"{}");
var token = jprefs.SelectToken(path);
if (token != null)
{
// how to set the value of the path?
}
else
// how to add the path and value, example {"global.defaults.sort": { "true" }}
}
what I mean by global.defaults.sort path is actually { global: { defaults: { sort: { true } } } }
public string SetPreference(string username, string path, string value)
{
if (!value.StartsWith("[") && !value.StartsWith("{"))
value = string.Format("\"{0}\"", value);
var val = JObject.Parse(string.Format("{{\"x\":{0}}}", value)).SelectToken("x");
var prefs = GetPreferences(username);
var jprefs = JObject.Parse(prefs ?? #"{}");
var token = jprefs.SelectToken(path) as JValue;
if (token == null)
{
dynamic jpart = jprefs;
foreach (var part in path.Split('.'))
{
if (jpart[part] == null)
jpart.Add(new JProperty(part, new JObject()));
jpart = jpart[part];
}
jpart.Replace(val);
}
else
token.Replace(val);
SetPreferences(username, jprefs.ToString());
return jprefs.SelectToken(path).ToString();
}
I have 2 login controls on a web application one on default and one on default2 (the naming convention will be updated after I get it working).
What I am doing is setting a cookie on each login that will send a connectionstring name from the login controls authenticate method. It is sending a string that is hard coded to a base class called Authenticate Users. The class is doing the following...
public class AuthenticatedUser : System.Web.UI.Page
{
public static string ConnectionString
{
get
{
HttpCookie myCookie = HttpContext.Current.Request.Cookies["connectionString"];
return GetConnectionStringFromName(myCookie);
}
set
{
HttpCookie oldCookie = HttpContext.Current.Request.Cookies["connectionString"];
oldCookie.Expires = DateTime.Now.AddDays(-1);
HttpCookie cookie = new HttpCookie("connectionString");
cookie.Value = value;
cookie.Expires = DateTime.Now.AddYears(100);
HttpContext.Current.Request.Cookies.Add(cookie);
string val = cookie.Value;
}
}
private static string GetConnectionStringFromName(HttpCookie myCookie)
{
string connectionStringName = myCookie.Value;
return ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
}
}
I am seding in the strings "database1" and "database2" depending on which login control they use. When I debug through the code, the connectionstring is setting all of the cookie information and everything works great for "database2" however everytime I log in using the form associated with "database1" it sets the cookie but when the get is called it is still referencing "database2"
Is this an issue because the cookies are named the same and do not overwrite eachother or update themselves or is there a problem with my code?
edit -- it is still not working with removing the cookies from the context, it still gives me the "database2" when I run "database1"
public static string ConnectionString
{
get
{
HttpCookie myCookie = HttpContext.Current.Request.Cookies["connectionString"];
return GetConnectionStringFromName(myCookie);
}
set
{
if (HttpContext.Current.Request.Cookies["connectionString"] != null)
{
ExpireCookies(HttpContext.Current);
}
HttpCookie cookie = HttpContext.Current.Response.Cookies["connectionString"];
cookie.Value = value;
cookie.Expires = DateTime.Now.AddYears(100);
HttpContext.Current.Response.Cookies.Add(cookie);
string val = cookie.Value;
}
}
private static string GetConnectionStringFromName(HttpCookie myCookie)
{
string connectionStringName = myCookie.Value;
return ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
}
private static void ExpireCookies(HttpContext current)
{
var allCookies = current.Request.Cookies.AllKeys;
foreach (var cook in allCookies.Select(c => current.Response.Cookies[c]).Where(cook => cook != null))
{
cook.Value = "";
cook.Expires = DateTime.Now.AddDays(-1);
current.Response.Cookies.Remove(cook.Name);
}
}
Final Edit It works...here is the working code if anyone is interested...
public static string ConnectionString
{
get
{
HttpCookie myCookie = HttpContext.Current.Request.Cookies["connectionString"];
return GetConnectionStringFromName(myCookie);
}
set
{
if (HttpContext.Current.Request.Cookies["connectionString"] != null)
{
ExpireCookies(HttpContext.Current);
}
var allCookies = HttpContext.Current.Request.Cookies.AllKeys;
HttpCookie cookie = new HttpCookie("connectionString");
cookie.Value = value;
cookie.Expires = DateTime.Now.AddYears(100);
HttpContext.Current.Request.Cookies.Add(cookie);
string val = cookie.Value;
}
}
private static string GetConnectionStringFromName(HttpCookie myCookie)
{
string connectionStringName = myCookie.Value;
return ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
}
private static void ExpireCookies(HttpContext current)
{
var allCookies = current.Request.Cookies.AllKeys;
foreach (var cook in allCookies.Select(c => current.Response.Cookies[c]).Where(cook => cook != null))
{
cook.Value = "";
cook.Expires = DateTime.Now.AddDays(-1);
current.Request.Cookies.Remove(cook.Name);
cook.Name = "";
}
}
you have part of the code needed (expiring the cookie). but you also need to remove from the context, try something like the following:
private static void ExpireCookies(HttpContext current)
{
var allCookies = current.Request.Cookies.AllKeys;
foreach (var cook in allCookies.Select(c => current.Response.Cookies[c]).Where(cook => cook != null))
{
cook.Value = "";
cook.Expires = DateTime.Now.AddDays(-1);
current.Response.Cookies.Remove(cook.Name);
}
}