How to dynamically initialize Culture in ASP.NET WebService Call? - asp.net

Can anyone tell me how can i dynamically initialize thread culture in a asp.net webservice call?
In my aspx pages i have a base page where i override the InitializeCulture() Method.
Note that the value of selected language is saved in Session State.

In Global.asax file you can set the current culture, even if its web service or web page.
// PreRequestHandlerExecute occurs after initialization of Session
void Application_PreRequestHandlerExecute(Object Sender, EventArgs e)
{
// check if session is required for the request
// as .css don't require session and accessing session will throw exception
if (Context.Handler is IRequiresSessionState
|| Context.Handler is IReadOnlySessionState)
{
string culture = "en-US";
if (Session["MyCurrentCulutre"] != null)
{
culture = Session["MyCurrentCulutre"] as String;
}
System.Threading.Thread.CurrentThread.CurrentCulture =
System.Globalization.CultureInfo.CreateSpecificCulture(culture);
}
}
You are changing your requirements, however Session object will not be available in Begin_Request method, you can do this in your web method.
[WebMethod]
public static string MyWebMethod()
{
String culture = Session["MyCurrentCulutre"] as String;
System.Threading.Thread.CurrentThread.CurrentCulture =
System.Globalization.CultureInfo.CreateSpecificCulture(culture);
return "My results";
}

Related

How to Encrypt and Decrypt cookie in an Existing Project without changing all pages code

I am working on a project with 1000s of pages in it which uses cookies. Now There comes an security issue , so I am planning to encrypt the cookie and decrypt when use it in page level.
Sample code i have used in Login page where my cookie gets created is as below:
Response.Cookies.Clear()
Response.Cookies("userinfo")("username") = "Pravin Kumar"
Response.Redirect("Home.aspx")
Now i wanna access that cookie in my HOME.aspx page . The code is as below.
Response.Write(Request.Cookies("userinfo")("username"))
This is how my project pages working till now and this enables user to view cookie in browser window like below :
Now My intention is i want to do some encrypting in LOGIN.aspx page and do the decryption in such a centralized place so that i no need to change all pages .
PS: I have tried with GLOBAL.asax page using
Sub Application_EndRequest(ByVal sender As Object, ByVal e As EventArgs)
End Sub
But it didn't helped out.Pls suggest me if any simplest method found.
you will have to use HttpModule to override the behavior of the cookie read/write.
here is the sample code:
firstly, in your HttpModule
public class CookieEncryptModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.PreSendRequestContent += Context_PreSendRequestContent;
context.BeginRequest += Context_BeginRequest;
}
private void Context_BeginRequest(object sender, EventArgs e)
{
HttpApplication httpApplication = sender as HttpApplication;
for (int i = 0; i < httpApplication.Request.Cookies.Count; i++)
{
var cookie = httpApplication.Request.Cookies[i];
cookie.Value = dencryptCookieValue(cookie.Value);
}
}
private void Context_PreSendRequestContent(object sender, EventArgs e)
{
HttpApplication httpApplication = sender as HttpApplication;
for (int i = 0; i < httpApplication.Response.Cookies.Count; i++)
{
var cookie = httpApplication.Response.Cookies[i];
cookie.Value = encryptCookieValue(cookie.Value);
}
}
private string encryptCookieValue(string value)
{
return Convert.ToBase64String(Encoding.UTF8.GetBytes(value));
}
private string dencryptCookieValue(string value)
{
try
{
return Encoding.UTF8.GetString(Convert.FromBase64String(value));
}
catch
{
//in case some system generated cookies like session id will not be encrypted by our code
return value;
}
}
}
then in your web.config
<system.webServer>
<modules>
<add name="encryptCookie" type="[your_namespace].CookieEncryptModule, [your_assemably_name]"/>
</modules></system.webServer>
after above is done,
you cookies now will be stored in client with base64,
but to you server side codes it's transparent, you don't need to change anything
[notice]: this will make all JS fail to read the cookie value

Setting cookie doesn't persist between web requests

I've created a brand new ASP.Net 4.6 MVC project, and have tried to set a value in the Requests Cookies collection and retrieve it in the next request. I'm using cookies because Session isn't available yet within the Application_BeginRequest method. Using the following code, the cookie value I ask for is null in every request I make, despite setting it.
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
protected void Application_BeginRequest()
{
var cookie = this.Request.Cookies.Get("Foo");
string value = cookie?.Value;
if (string.IsNullOrEmpty(value))
{
cookie = new HttpCookie("Foo", "Bar");
cookie.Expires = System.DateTime.UtcNow.AddHours(1);
this.Request.Cookies.Add(cookie);
}
}
protected void Application_EndRequest()
{
var cookie = this.Request.Cookies.Get("Foo");
string value = cookie?.Value;
}
}
What am I doing wrong? All of the posts I've seen relating to cookies shows setting/getting them in this fashion, with Request.Cookies.Get/Request.Cookies.Add.
You are not setting the cookie in this code you are only reading it, I made this same mistake. Use this
this.Response.Cookies.Add(cookie);
instead of
this.Request.Cookies.Add(cookie);
You should now see it in google chromes Application -> Cookies for your site
If you want to get state for each request, you have to do in Application_AcquireRequestState
Your Application_AcquireRequestState implementation should be :
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
var cookie = this.Request.Cookies.Get("Foo");
string value = cookie?.Value;
if (string.IsNullOrEmpty(value))
{
cookie = new HttpCookie("Foo", "Bar");
cookie.Expires = System.DateTime.UtcNow.AddHours(1);
this.Request.Cookies.Add(cookie);
}
}

Call Membership.GetUser() from Session_Start in global.asax - ASP.NET identity

I'm trying trying to call Membership.GetUser from from Session_Start in global.asax using ASP.NET identity 2.0
When .Create() is called I get the following erorr at Membership.GetUser:
An exception of type 'System.Data.SqlClient.SqlException' occurred in
System.Web.dll but was not handled in user code
Additional information: Could not find stored procedure
'dbo.aspnet_CheckSchemaVersion'.
I suspect this has something to do with OWIN not being initialized yet?
Does anyone know if it's possible to get the current GUID from application_start?
Here's my code...
Global.asax
protected void Session_Start(Object sender, EventArgs e)
{
SessionData.Create();
}
SessionData:
public class SessionData
{
public static void Create()
{
using (var db = new BeatBoxV2Context())
{
var membershipUser = Membership.GetUser();
var providerUserKey = membershipUser?.ProviderUserKey;
if (providerUserKey == null) return;
var guid = (Guid)providerUserKey;
var account = db.Account.Find(guid);
var sessionData = new SessionData
{
UserPermissions= db.Permissions.Where(h => h.Guid == guid).ToList()
};
}
}
public List<Permissions> UserPermissions
{
get { return HttpContext.Current.Session["UserPermissions"] != null ? (List<HolterPermission>)HttpContext.Current.Session["UserPermissions"] : null; }
set { HttpContext.Current.Session["UserPermissions"] = value; }
}
}
OK So the solution was as follows:
Attach the database in App_Data in SQL Express
Run aspnet_regsql from the VS Command Prompt

Propagting the resource culture change in master page to the content web pages

I'm a noob when it comes to web applications. But i'm trying my best to learn it using ASP.NET 2.0 and sorry for the long post.
I have a master page(M1) and 3 different content pagesC1,C2,C3 which basically use the master page M1 for filling its respective contents in the content placeholder.
All the web-forms are localized and appropriate language resource strings are added in the resource (xml) files ex: Resource.en-US.xml,Resource.de-DE.xml and so on.Finally the resources are referred in the code after setting up the appropriate current culture and current uiculture.
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
//where the btnSubmit is a control on the form
btnSubmit.Text = rm.GetString("Submit", Thread.CurrentThread.CurrentCulture);
Now comes the question, I have included an option of changing the display language in the master page available to the user as an asp:linkbutton with an asp:image. Whenever the user clicks the linkbutton for the desired language, the content page controls shall display the whole content strings corresponding to the culture selected.
How do i achieve this ?
Do i have to implement Session variables to include the selected
language ? Or storing in Cookie would also do the job ?
What i tried
On master page load event. I tried calling a method SetCultureSpecificInformation, which basically sets the culture and uiculture properties of CurrentThread and store the selected language inside a session variable.
Also a similar implementation on the asp:linkbutton OnClick eventhandler. In this case it modifies the session variable.
Finally refer the session variable on the content web page OnPage_Load event.
But somehow the above approach is not yielding desired results. The switching of language is not consistent. Anyone out there who can help me out with a good enough design approach for implementing the same.
Thanks in advance
Add Global.asax file: write this piece of code
void Application_BeginRequest(Object sender, EventArgs e)
{
// Code that runs on application startup
HttpCookie cookie = HttpContext.Current.Request.Cookies["CultureInfo"];
if (cookie != null && cookie.Value != null)
{
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(cookie.Value);
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cookie.Value);
}
else
{
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en");
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en");
}
}
And on Masterpage page
protected void ddlanguage_SelectedIndexChanged(object sender, EventArgs e)
{
Session["language"] = ddlanguage.SelectedValue;
//Sets the cookie that is to be used by Global.asax
HttpCookie cookie = new HttpCookie("CultureInfo");
cookie.Value = ddlanguage.SelectedValue;
Response.Cookies.Add(cookie);
//Set the culture and reload for immediate effect.
//Future effects are handled by Global.asax
Thread.CurrentThread.CurrentCulture = new CultureInfo(ddlanguage.SelectedValue);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(ddlanguage.SelectedValue);
if (cookie.Value == "en")
{
Session["ddindex"] = 0;
}
else if (cookie.Value == "fr")
{
Session["ddindex"] = 1;
}
else if (cookie.Value == "de")
{
Session["ddindex"] = 2;
}
Server.Transfer(Request.Path);
}
}
In my case used a couple of buttons for setting culture from the master page, then used this code in the master page's code behid:
protected void IdiomButton_Click(object sender, ImageClickEventArgs e)
{
ImageButton theButton = (ImageButton)sender;
Session["culture"] = theButton.ID == "ItalianButton" ? CultureInfo.CreateSpecificCulture("it-IT") : CultureInfo.CreateSpecificCulture("en-US");
Response.Redirect(Request.RawUrl);
}
Then in every child page I used :
protected override void InitializeCulture()
{
if (Session["culture"] != null)
System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(Session["culture"].ToString());
else
System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("it-IT");
}

ASP.NET: Changing a site's culture programmatically

i'm trying to set my website's culture programmatically, so when a user clicks a button they can change the text on the page from english to spanish. here's my code:
protected void btnChangeLanguage(object sender, EventArgs e)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("es");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("es);
}
<asp:Label ID="lblDisplay" runat="server" meta:ResourceKey="lblDisplay" />
<asp:Button ID="btnChangeLanguage" runat="server" Text="Change Language"
OnClick="btnChangeLanguage_Click" />
i have a Default.aspx.resx file with a key/value of: lblDisplay.text/English
and a Default.aspx.es.resx file with a key/value of: lblDisplay.text/Espanol
i can't get my Label's text to change from "English" to "Spanish". anyone see what i'm doing wrong?
ASP.Net threads are used for the lifetime of one request, not a user's entire session. Worse, sometimes the framework will recycle the same thread to handle additional requests rather than return it to the pool and get a new one (it's not that big a deal because the next request will initialize the culture again, but still).
Instead, you need to override the InitializeCulture() method for your page. See this link for more detail:
http://msdn.microsoft.com/en-us/library/bz9tc508.aspx
Create Session variable called "CurrentUI". and change it on link buttons event
eg:
Here i have two link buttons for each language
protected void EnglishLinkButton_Click(object sender, EventArgs e) {
Session["CurrentUI"] = "en-US";
Response.Redirect(Request.Url.OriginalString);
}
protected void SinhalaLinkButton_Click(object sender, EventArgs e) {
// සිංහල (ශ්‍රී ලංකා)
Session["CurrentUI"] = "si-LK";
Response.Redirect(Request.Url.OriginalString);
}
Now you need to override the InitializeCulture() in the base class of page
protected override void InitializeCulture() {
if (Session["CurrentUI"] != null) {
String selectedLanguage = (string)Session["CurrentUI"];
UICulture = selectedLanguage;
Culture = selectedLanguage;
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture(selectedLanguage);
Thread.CurrentThread.CurrentUICulture = new
CultureInfo(selectedLanguage);
}
base.InitializeCulture();
}
Note that I used
//Response.Redirect(Request.Url.OriginalString);
after assigning culture key into the session in order to create a second post back to the page.
Because InitializeCulture() happens before the event and change will be applicable in the next request only.

Resources