Why is my language switching automatically in ASP.NET 2.0? - localization

I am working on an ASP.NET 2.0 web solution which currently runs en-GB and zh-HK languages as the 2 current languages for the site. Others will be added at a later date.
One of the requirements is that the user can choose to override the language displayed to another language. Therefore users in Hong Kong can view the site in English and vice versa.
My 2 resource files are
Resources.resx (for English - default translations)
Resources.zh-HK.resx (for Chinese)
The site performs this logic
Load user details
Check if user has overridden the preferred language
If they have, set the Thread.CurrentThread.CurrentUICulture to this language.
If they haven't, use the browsers default.
This is implemented in the following code:
//This method is written in a base page, which all pages in the site derive from
protected override void InitializeCulture()
{
User user = /*Load custom user object...*/;
string threadLanguage = Thread.CurrentThread.CurrentUICulture.IetfLanguageTag;
//If the browser is using a different language,
//but the has chosen a preferred language,
//change the CurrentUICulture over.
if (!threadLanguage.Equals(user.Language, StringComparison.OrdinalIgnoreCase))
{
CultureInfo userLanguageCulture = CultureInfo.CreateSpecificCulture(user.Language);
Thread.CurrentThread.CurrentUICulture = userLanguageCulture;
}
base.InitializeCulture();
}
I have also configured the web.config to pick up the uiCulture automatically with
<globalization uiCulture="auto"/>
For some very very odd reason, some users (even en-GB users) are finding the language is switching over the zh-HK for no reason whatsoever - sometimes between pages! I have added some debugging code to these pages which should reveal more information in the coming days. All it has revealed so far is that users are not necessarily from zh-HK, some are from zh-CN or zh-TW. Although this might help, because en-GB users are seeing zh-HK I think it is just a red herring.
What I have noticed is that the switch over occurs on page content (those inheriting from the base page, which the IntializeCulture() method exists). The custom user controls I have written do not experience this problem and appear in the correct language configured by the user. Therefore a page would have combinations of both English and Chinese content - eek!
Can anyone give guidance as to if I am coding this correctly, or an alternative way of approaching the requirements.
Thanks in advance,
Dominic
P.S. This is an intermittent problem and not a permanent. There seems to be no common action that replicates this issue. It just - happens.
P.P.S Here is an image of the problem in action:
Update 23 Sep 09:
After trying to change it to Page.Culture, I am still having more intermittent problems.
I have a couple of ideas at why this could possibly be occurring, but am unable to justify my 'hypothesis':
We are using IIS 5.0 Isolation Mode, meaning only aspnet_wp.exe is running and not w3wp.exe for each IIS instance.
Reporting Services is also running on the server, generating reports for Hong Kong.
The fault occurs more frequently when the site was under heavy load - I assume due to large reports being generated.
Apart from that, I do not know what else could cause the problem. I would show another screenshot, but the problem is identical and did appear in the same place as the previous screenshot showed.
Update 25 Sep 09:
I think we I might have solved it. In our Web.config, there is a tag that was configured as follows:
<globalization uiCulture="auto" culture="auto"/>
After removing that, after initial testing, it has yet to turn up!
Update 13 Oct 09:
The problem has turned up again :-(
Update 26 Oct 09:
It seems that if another user of the site changes their preferred language, it affects all other users on the site! Although their preferred language is set, somehow someone else's language switch affects the other users of the site!

Shouldn't it be using Page.Culture, not Thread?

After a long, long time I finally worked out why this problem occurred.
The site started off as a frameset.asp, hosting 3 .NET frames - top, middle, bottom. What I noticed, is that .NET generated 3 sessions, and therefore any changes only affected one frame.
In a way, it doesn't completely explain why only parts of the page were working, but it has resolved quite a few issues regarding some of the odd Repsonse.Redirects we were going.
In summary, the frameset.asp, was replated with a frameset.aspx, which generates a single cookie / Session ID for all frames.

Related

Alternative to custom protocols (URI schemes)

I have been extensively using a custom protocol on all our internal apps to open any type of document (CAD, CAM, PDF, etc.), to open File Explorer and select a specific file, and to run other applications.
Years ago I defined one myprotocol protocol that executes C:\Windows\System32\wscript.exe passing the name of my VBScript and whatever argument each request has. The first argument passed to the script describe the type of action (OpenDocument, ShowFileInFileExplorer, ExportBOM, etc.), the following arguments are passed to the action.
Everything worked well until last year, when wscript.exe stopped working (see here for details). I fixed that problem by copying it to wscript2.exe. Creating a copy is now a step in the standard configuration of all our computers and using wscript2.exe is now the official configuration of our custom protocol. (Our anti-virus customer support couldn't find anything that interacts with wscript.exe).
Today, after building a new computer, we found out that:
Firefox doesn't see wscript2.exe. If I click on a custom protocol link, then click on the browse button and open the folder, I only see a small subset of .exe files, which includes wscript.exe, but doesn't include wscript2.exe (I don't know how recent this problem is because I don't personally use FireFox).
Firefox sees wscript.exe, but it still doesn't work (same behavior as described in my previous post linked above)
Chrome works with wscript2.exe, but now it always asks for confirmation. According to this article this seems to be the new approach, and things could change again soon. Clicking on a confirmation box every time is a big no-no with my users. This would slow down many workflows that require quickly clicking hundreds of links on a page and, for example, look at a CAD application zooming to one geometry in a large drawing.
I already fixed one problem last year, I am dealing with another one now, and reading that article scares me and makes me think that more problems will arise soon.
So here is the question: is there an alternative to using custom protocols?
I am not working on a web app for public consumption. My custom protocol requires the VBScript file, the applications that the script uses and tons of network shared folders. They are only used in our internal network and the computers that use them are manually configured.
First of all, that's super risky even if it's on internal network only. Unless computers/users/browsers are locked out of internet, it is possible that someone guesses or finds out your protocol's name, sends link to someone in your company and causes a lot of trouble (possibly loss too).
Anyway...
Since you are controlling software on all of the computers, you could add a mini-server on every machine, listening to localhost only, that simply calls your script. Then define host like secret.myprotocol to point to that server, e.g., localhost:1234.
Just to lessen potential problems a bit, local server would use HTTPS only, with proper certificate, HSTS and HPKP set to a very long time (since you control software, you can refresh those when needed). The last two, just in case someone tries to setup the same domain and, for whatever reason, host override doesn't work and user ends up calling a hostile server.
So, links would have to change from myprotocol://whatever to https://secret.myprotocol/whatever.
It does introduce new attack surface ("mini-server"), but should be easy enough to implement, to minimize size of that surface :). "Mini-server" does not even have to be real www server, a simple script that can listen on socket and call wscript.exe would do (unless you need to pass more info to it).
Real server has more code that can have bugs in it, but also allows to add more things, for example a "pass through" page, that shows info "Opening document X in 3 seconds..." and a "cancel" button.
It could also require session login of some kind (just to be sure it's user who requests action, and not something else).
The title of this blog post says it all: Browser Architecture: Web-to-App Communication Overview.
It describes a list of Web-to-App Communication techniques and links to dedicated posts for some of them.
The first in the list is Application Protocols, which I have been using for years already, and it started to crumble in the last year or so (hence my question).
The fifth is Local Web Server, which is the one described by ahwayakchih.
UPDATE (this update follows the update on the blog post above mentioned)
Apparently I wasn't the only one thinking that this change in behavior was a regression, so a workaround has been issued: the old behavior (showing a checkbox that allows to remember the answer) can be restored by adding these keys to the registry:
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Edge]
"ExternalProtocolDialogShowAlwaysOpenCheckbox"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome]
"ExternalProtocolDialogShowAlwaysOpenCheckbox"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Chromium]
"ExternalProtocolDialogShowAlwaysOpenCheckbox"=dword:00000001

Disable multi-tab browsing for single session/user

[Disclaimer: I'm not sure if this kind of question is accepted here as it is about a piece of software deployed already. Rest assured I didn't drop any confidential information. Also do tell me if I violated any rules in SO by posting this so I can take it down immediately]
I have a working Learning Management System web application and I recently received a bug report about a button not showing. After investigating, I have proved that the user was not using the web app as intended. When taking an exam, he was opening multiple tabs to exploit the feature that informs him whether the answer was correct or not. He then will use this information to eliminate the wrong answers and submit all the right answers in another tab/window.
I'm using Rails 4.2. Is there a way to prevent multi-tab browsing? I'm thinking like if a user is signed in and he attempted to open a new tab of the webapp, he should see something like "Please use one tab" and all the features/hyperlinks/buttons are disabled.
Here's a screenshot of how I proved he was using multiple tabs. Notice that there are multiple logs of the same attempt # because the current implementation allows saving a study session and resuming later (this is the part that's exploited). The opening of multiple tabs searches for the most recent attempt session and continues from there. This is also the reason why most of the sessions don't have a duration value -- the user only finishes a study session for one tab (by clicking a button that ends the study session). The system cannot compute for the duration because the other sessions don't have an end timestamp.
-
This is what a single-tab user looks like:
This is more of an application misuse issue more than a bug.
You should add protection not only from multi tab, but for multi browsers aw well, so it can't be purely FrontEnd check.
One of the solutions could be using ActionCable to check if a user has an active connection already and then act accordingly.
Another, for example, generate a GUID in JS and pass it with every answer. If its different from previous answer, it means user opened a new window.
But of course the solution would depend on your current architecture, without knowing how do you currently organise client-server communication it's hard to give exact and optimal solution.
I found an answer here. I just placed this js in the application view to prevent any extra instance of the website.
Thanks for everyone who pitched in.

Google Analytics causing website to duplicate POSTs

We've noticed a very strange behavior change on our website (asp.net MVC) starting early morning (GMT) on the 12'th of January this year (2018).
Http POSTs from the site started firing twice (unconfirmed, but we suspect sometimes more than twice), and scouring high and low we couldn't find that we'd changed anything.
One of the few things we dynamically load is Google Analytics (specifically Google Tag Manager), and in the course of trial-and-error we tried disabling everything external (which made the phenomenon disappear) and then re-enabling them one-by-one, once we came to re-enabling GA the problem re-appeared.
We also tried removing everything except GA and the problem persisted.
When searching we can't find that anything has been updated in GA, so it's very unclear why it suddenly started, and we have also been unable to find anyone else reporting the same problem (either historically or presently).
Our current best guess is that one of GA's dependencies have updated, and either it contains a bug, or it's exposing an already existing fault in our code.
Has anyone else noticed the same problem? Anyone find something in their code that caused the strange behavior of GA?
I found the error, it was caused by two erroneously set up triggers.
Both triggers were form submit type, and both had double activators, one "Activate trigger when all conditions are met" and one "Activate trigger on specific forms".
The problem was that both "all conditions" activators were set to "url matches regular expression .*", where as the second activator for both targeted a correct Form Path for each respectively.
Whoever set it up must have assumed that Google Tag Manager was using a logical "and" between the two activators (not an unrealistic assumption), but based on my testing at least it seems that the trigger activates on either activator matching.
I couldn't see any reason for the first regex match towards ".*", so the fix was to simply supply a unique url expression for each trigger.
No explanation yet as to why it suddenly became a problem, because the configuration has been wrong for a couple of months at least.
P.S. For whatever reason our GTM is not in English, so take my quoted names on fields/etc with a grain of salt as they are translated.
Update
The website uses ajax to post the forms, the combination of that and the "Await tags" flag on the triggers are looking as likely sources of why the combined conditions were not acting as expected.
Which means a non-announced performance-update to GTM regarding "Await tags" could have been the catalyst which caused the problem to start occuring with alarming frequency.

XPages NoAccessSignal exception

A customer has a number of XPages applications that have a jQuery Mobile user interface for use on iPads. They have been working fine for a long time. There have been no application code changes, but recently users are reporting strange behaviour in the user interface across a number of the applications.
This seems to be related to multi-value fields where JQM shows a long list of values in an overlay. When then selecting a second multi-value field the pop-up box is being displayed but then immediately replaced with the overlay for the first field but without any values.
The Domino server is 8.5.3 FP4 and the administrators tell me there have been no environment and security changes recently.
In addition to the above I am also seeing the following errors occurring :-
16/12/15 15:54: Exception Thrown
com.ibm.xsp.acl.NoAccessSignal
at com.ibm.domino.xsp.module.nsf.NotesContext.checkAccess(NotesContext.java:1631)
at com.ibm.domino.xsp.module.nsf.NotesContext.serverProcessSignedResource(NotesContext.java:975)
at com.ibm.domino.xsp.module.nsf.NotesContext.setSignerSessionRights(NotesContext.java:946)
at com.ibm.domino.xsp.module.nsf.ModuleClassLoader$DynamicClassLoader.loadClass(ModuleClassLoader.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:626)
at com.ibm.domino.xsp.module.nsf.ModuleClassLoader.loadClass(ModuleClassLoader.java:171)
at java.lang.ClassLoader.loadClass(ClassLoader.java:626)
at com.ibm.designer.runtime.Application.loadClass(Application.java:708)
at com.ibm.xsp.library.ApplicationFacesClassLoader.loadClass(ApplicationFacesClassLoader.java:54)
at com.ibm.xsp.page.compiled.CompiledPageDriver.getClassForPageName(CompiledPageDriver.java:169)
at com.ibm.xsp.page.compiled.CompiledPageDriver.loadPage(CompiledPageDriver.java:61)
at com.ibm.xsp.application.ViewHandlerExImpl._createViewRoot(ViewHandlerExImpl.java:489)
at com.ibm.xsp.application.ViewHandlerExImpl.createViewRoot(ViewHandlerExImpl.java:557)
at com.ibm.xsp.application.ViewHandlerExImpl.doCreateView(ViewHandlerExImpl.java:141)
at com.ibm.xsp.application.ViewHandlerEx.createView(ViewHandlerEx.java:90)
at com.ibm.xsp.webapp.FacesServlet.serviceView(FacesServlet.java:238)
at com.ibm.xsp.webapp.FacesServletEx.serviceView(FacesServletEx.java:204)
at com.ibm.xsp.webapp.FacesServlet.service(FacesServlet.java:160)
at com.ibm.xsp.webapp.FacesServletEx.service(FacesServletEx.java:138)
at com.ibm.xsp.webapp.DesignerFacesServlet.service(DesignerFacesServlet.java:103)
at com.ibm.designer.runtime.domino.adapter.ComponentModule.invokeServlet(ComponentModule.java:583)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.invokeServlet(NSFComponentModule.java:1281)
at com.ibm.designer.runtime.domino.adapter.ComponentModule$AdapterInvoker.invokeServlet(ComponentModule.java:860)
at com.ibm.designer.runtime.domino.adapter.ComponentModule$ServletInvoker.doService(ComponentModule.java:803)
at com.ibm.designer.runtime.domino.adapter.ComponentModule.doService(ComponentModule.java:572)
at com.ibm.domino.xsp.module.nsf.NSFComponentModule.doService(NSFComponentModule.java:1265)
at com.ibm.domino.xsp.module.nsf.NSFService.doServiceInternal(NSFService.java:658)
at com.ibm.domino.xsp.module.nsf.NSFService.doService(NSFService.java:481)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.doService(LCDEnvironment.java:341)
at com.ibm.designer.runtime.domino.adapter.LCDEnvironment.service(LCDEnvironment.java:297)
at com.ibm.domino.xsp.bridge.http.engine.XspCmdManager.service(XspCmdManager.java:272)
There doesn't seem to be any indication as to which application or XPage these exceptions are related to. And I do not know whether this is related to the issues being seen in the user interface of the various applications.
Can anyone shed any light on this exception or what I should be looking for?
What jumps out are these lines:
at com.ibm.domino.xsp.module.nsf.NotesContext.serverProcessSignedResource(NotesContext.java:975)
at com.ibm.domino.xsp.module.nsf.NotesContext.setSignerSessionRights(NotesContext.java:946)
I don't know which application is causing the problem, but it looks it may be having a problem assigning signer rights. It may be worth checking for multiple signers of design elements.
The com.ibm.xsp.acl.NoAccessSignal exception is thrown when an anonymous user tries to access a protected XPages resource. So this exception has nothing to do with the strange behaviour that you are experiencing.

Changing language by domain (localization/globalization)

I have a webforms website that needs to be set either to danish (DK) or swedish (SE) language depending on the domain (.se/.dk). Theres both some global and local resources. Mostly local. The language needs to be set once, global for the entire application, once the clients lands on the page (session start).
The auto settings in web.config will not be sufficient, cause some of the users will have english settings on their browsers, launching the default resources (which is danish). Not optimal if youre a swedish user with english settings.
If i run an overrided method of InitializeCulture() on for example default.aspx and ask for host/domain and set the langauge from that, the culture will be reset to the default resources as soon as I leave the default page. Setting the culture in Session_Start in global.asax will do the same thing. Works on landing page, resets on sub page.
Whats the right way to do this?
I guess the question comes down to: Do I really have to call InitializeCulture() on every single page?
Apparently yes - I have to call InitializeCulture on every single page:
InitializeCulture() on every single page necessary?

Resources