I've been trying to get a master page to load dynamically when it is detected that the device accessing the site is a mobile device.
However I can't seem to get it to load the correct master page as it always loads the default primary.master regardless of whether the device is detected as a mobile or desktop system.
Can anyone help?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
public partial class _Default : System.Web.UI.Page
{
protected void Page_PreInt(object sender, EventArgs e)
{
if (Request.Browser.IsMobileDevice == true)
{
MasterPageFile = "~/Mater Pages / Mobile Primary.master";
}
else
{
MasterPageFile = "~/Mater Pages /Primary.master";
base.OnPreInit(e);
}
}
protected void Page_Load(object sender, EventArgs e)
{
// If for any reason this page needs to be made inaccessible then remove the tags on either side of the text//
//Response.Redirect("~/Error Page.aspx");//
}
}
Request.Browser.IsMobileDevice is not reliable. The following helper method could detect a little bit more.
If you want reliable device detection, you want to use commercial service such as 51Degrees.
Event should be Page_PreInit (not Page_PreInt); you have a typo.
protected void Page_PreInit(object sender, EventArgs e)
{
// *** For debugging, I inverted if statement. You should do the same. ****
if (!IsMobileBrowser(HttpContext.Current))
MasterPageFile = "~/MaterPages/Primary.master";
else
MasterPageFile = "~/MaterPages/MobilePrimary.master";
// *** You do not need to call base.OnPreInit(e); ***
}
public static bool IsMobileBrowser(HttpContext context)
{
// first try built in asp.net check
if (context.Request.Browser.IsMobileDevice)
{
return true;
}
// then try checking for the http_x_wap_profile header
if (context.Request.ServerVariables["HTTP_X_WAP_PROFILE"] != null)
{
return true;
}
// then try checking that http_accept exists and contains wap
if (context.Request.ServerVariables["HTTP_ACCEPT"] != null &&
context.Request.ServerVariables["HTTP_ACCEPT"].ToLower().Contains("wap"))
{
return true;
}
// Finally check the http_user_agent header variable for any one of the following
if (context.Request.ServerVariables["HTTP_USER_AGENT"] != null)
{
// List of all mobile types
string[] mobiles =
new[]
{
"android", "opera mini", "midp", "j2me", "avant", "docomo", "novarra", "palmos", "palmsource",
"240×320", "opwv", "chtml",
"pda", "windows ce", "mmp/", "blackberry", "mib/", "symbian", "wireless", "nokia", "hand", "mobi",
"phone", "cdm", "up.b", "audio", "sie-", "sec-", "samsung", "htc", "mot-", "mitsu", "sagem", "sony",
"alcatel", "lg", "eric", "vx", "nec", "philips", "mmm", "xx", "panasonic", "sharp", "wap", "sch",
"rover", "pocket", "benq", "java", "pt", "pg", "vox", "amoi", "bird", "compal", "kg", "voda",
"sany", "kdd", "dbt", "sendo", "sgh", "gradi", "dddi", "moto", "iphone"
};
// Check if the header contains that text
var userAgent = context.Request.ServerVariables["HTTP_USER_AGENT"].ToLower();
return mobiles.Any(userAgent.Contains);
}
return false;
}
Related
I am building a program in C# to be used in one of my course at a college to demonstrate how Asynchronous connections work using RS-232 and two computers connected together. My course is not about programming, but data networks, so the connectivity is what I am looking for.
picture 1 - sample layout of GUI using Visual Studio 2015
One of the features I want to implement in my program is to show how a Master-slave, simplex connection works (i.e. the program can choose between been a master to send input from the keyboard; or slave to only receive information and print it on a textbox).
What I have already is the capability of initializing the serial port with specific characteristics (baud rate, data bits, stop bits, etc). This features are selected using combo boxes from the GUI, and assigned to the port when the user clicks a button to "open the port".
What I don't know is how to create the "slave" part of the program. My idea of what I could do is, after you choose the program to be "slave", you open the port waiting for some sort of flag or event to trigger when the input buffer has data stored.
I've been reading several forums and I can't find anything similar to what I need. I have, however, tested multiple alternatives that I believed would bring me closer to what I need with little to no result. I come to ask for an idea of what I could be doing wrong, or suggestions on how to tackle this problem. The problematic lines are bolded (or 2 stars ( * ) ):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace SerialCommTester
{
public partial class frmSerialComm : Form
{
static SerialPort _PuertoSerial;
public frmSerialComm()
{
InitializeComponent();
getAvailablePorts();
}
//---------------------------------my functions--------------------------------------
void getAvailablePorts()
{
string[] ports = SerialPort.GetPortNames();
cmbPortList.Items.AddRange(ports);
}
void activatePort()
{
//Note that all the combo boxes are named somewhat accordingly to what the information they are meant to display.
if (cmbPortList.Text != "" && cmbBaudRate.Text != "" && cmbParity.Text != "" && cmbStopBits.Text != "")
{
_PuertoSerial.PortName = cmbPortList.Text;
_PuertoSerial.BaudRate = Convert.ToInt32(cmbBaudRate.Text);
_PuertoSerial.RtsEnable = true;
_PuertoSerial.DtrEnable = true;
_PuertoSerial.DataBits = Convert.ToInt32(cmbDataBits.Text);
if (cmbParity.Text == "Even") { _PuertoSerial.Parity = Parity.Even; }
else if (cmbParity.Text == "Odd") { _PuertoSerial.Parity = Parity.Odd; }
else if (cmbParity.Text == "Space") { _PuertoSerial.Parity = Parity.Space; }
else if (cmbParity.Text == "Mark") { _PuertoSerial.Parity = Parity.Mark; }
else { _PuertoSerial.Parity = Parity.None; }
if (cmbStopBits.Text =="2") { _PuertoSerial.StopBits = StopBits.Two; }
else if (cmbStopBits.Text == "1.5") { _PuertoSerial.StopBits = StopBits.OnePointFive; }
else { _PuertoSerial.StopBits = StopBits.One; }
if (cmbHandShake.Text == "Software Flow Control") { _PuertoSerial.Handshake = Handshake.XOnXOff; }
else if (cmbHandShake.Text == "Hardware Flow Control") { _PuertoSerial.Handshake = Handshake.RequestToSend; }
else { _PuertoSerial.Handshake = Handshake.None; }
_PuertoSerial.ReadTimeout = 500;
_PuertoSerial.WriteTimeout = 500;
_PuertoSerial.Open();
//in my understanding, this line of code is needed to handle data being received. Does it trigger a flag or something?
**_PuertoSerial.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);**
}
else
{
txtRecieve.Text = "Input selection missing 1 or more characteristics";
}
}
**
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort testing = (SerialPort)sender;
txtRecieve.AppendText(testing.ReadExisting()); //txtRecieve cannot be reached within this function. It indicates the following error: "An object reference is required for the non-static field, method, or property 'frmSerialComm.txtRecieve'
}
**
void enableDisableGUI(bool[] input)
{
grpConnection.Enabled = input[0];
grpCharacteristics.Enabled = input[1];
btnOpenPort.Enabled = input[2];
btnClosePort.Enabled = input[3];
txtSend.Enabled = ((cmbControlMasterSlave.Text == "Slave") ? false : true);
}
//----------------------------C# objects / functions--------------------------------------
private void btnOpenPort_Click(object sender, EventArgs e)
{
try
{
_PuertoSerial = new SerialPort();
activatePort();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Message ", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
bool[] format = { false, false, false, true};
enableDisableGUI(format);
}
private void btnClosePort_Click(object sender, EventArgs e)
{
_PuertoSerial.Close();
bool[] format = { true, true, true, false};
enableDisableGUI(format);
}
private void txtSend_KeyPress(object sender, KeyPressEventArgs e)
{
_PuertoSerial.Write(e.KeyChar.ToString()); //this is how I send data through the serial port.
}
private void btnClearTxts_Click(object sender, EventArgs e)
{
txtRecieve.Clear();
txtSend.Clear();
}
} //class closes
} //program closes
I am not an experienced programmer, I just want to create something useful for my students. Any constructive criticism will be highly appreciated.
I don't have any definitive answers for you. You code looks like it should provide what you need once you get past the two possible glitches.
I think you should attach your SerialDataReceivedEventHandler BEFORE
you call _PuertoSerial.Open().
It may have no effect since event handlers can normally be enabled/disabled dynamically, but I base the advice on the following comment taken from the .Net source code for SerialPort on MSDN.
// all the magic happens in the call to the instance's .Open() method.
// Internally, the SerialStream constructor opens the file handle, sets the device control block and associated Win32 structures, and begins the event-watching cycle.
The "object reference" error might be resolved by removing the
static modifier from your DataReceivedHandler. If not, or if that
static modifier is necessary for some reason, then perhaps the
txtRecieve control has a private modifier which needs to be changed
to internal or public. You should be able to use Visual Studio in
debug mode to step into the InitializeComponent() method and see
where txtRecieve is being instantiated.
Well, I believe that I needed to read more. This is how I solved the problem (if this is not the real solution, at least is working for now):
I moved the "SerialDataReceivedEventHandler" line before the _PuertoSerial.open();
I followed the suggestions from this article:
https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(EHInvalidOperation.WinForms.IllegalCrossThreadCall);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5.2);k(DevLang-csharp)&rd=true
So my funtions (one existings + a new one) look like this:
void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
printReceivedText(_PuertoSerial.ReadExisting());
}
private void printReceivedText(string text)
{
if (this.txtSend.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(printReceivedText);
this.Invoke(d, new object[] { text });
}
else
{
this.txtRecieve.AppendText(text);
_PuertoSerial.DiscardInBuffer();
}
}
For now seems to be working fine. The final testing will come when I connect another terminal and see the program interacting with each other.
After I've added the Done button on iOS numeric keyboard in Xamarin Forms, I encountered another problem: the Done button not firing Completed event (like return button does).
On my way to implement this, I found the following code on Xamarin Forums:
using System;
using System.Drawing;
using System.Reflection;
using Xamarin.Forms.Platform.iOS;
using Xamarin.Forms;
using UIKit;
using KeyboardTest.iOS;
using KeyboardTest;
[assembly: ExportRenderer(typeof(EntryDone), typeof(EntryDoneRenderer))]
namespace KeyboardTest.iOS
{
public class EntryDoneRenderer : EntryRenderer
{
// used to cache the MethodInfo so we only have the reflection hit once
private MethodInfo baseEntrySendCompleted = null;
public EntryDoneRenderer ()
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged (e);
if (this.Element.Keyboard == Keyboard.Numeric)
{
// only want the Done on the numeric keyboard type
UIToolbar toolbar = new UIToolbar (new RectangleF (0.0f, 0.0f, (float)Control.Frame.Size.Width, 44.0f));
var doneButton = new UIBarButtonItem (UIBarButtonSystemItem.Done, delegate {
this.Control.ResignFirstResponder ();
Type baseEntry = this.Element.GetType();
if(baseEntrySendCompleted==null)
{
// use reflection to find our method
baseEntrySendCompleted = baseEntry.GetMethod("SendCompleted",BindingFlags.NonPublic|BindingFlags.Instance);
}
try
{
baseEntrySendCompleted.Invoke(this.Element,null);
}
catch (Exception ex)
{
// handle the invoke error condition
}
});
toolbar.Items = new UIBarButtonItem[] {
new UIBarButtonItem (UIBarButtonSystemItem.FlexibleSpace),
doneButton
};
this.Control.InputAccessoryView = toolbar;
}
}
}
}
I don't know why, but I receive the error:
System.NullReferenceException: Object reference not set to an instance of an object
at myGame.iOS.DoneEntryRenderer.<OnElementChanged>m__0 (System.Object , System.EventArgs ) [0x0005d] in /Users/silviu/Projects/myGame/iOS/DoneEntry.cs:37
On that line I have the code:
baseEntrySendCompleted.Invoke(this.Element, null);
I’ve tried to debug the problem and I found that the SendCompleted method does not exist, but I don’t understand how to solve this problem in the lastest version of Xamarin, because I think on the moment when that guy posted the code, worked.
Thanks!
SendCompleted() was actually added for IEntryController so you don't need to use reflection for this any longer. In fact it appears that way no longer works. Just call SendCompleted() directly from your button press like so.
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
var toolbar = new UIToolbar(new CGRect(0.0f, 0.0f, Control.Frame.Size.Width, 44.0f));
toolbar.Items = new[]
{
new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace),
new UIBarButtonItem(UIBarButtonSystemItem.Done, delegate {
Control.ResignFirstResponder();
((IEntryController)Element).SendCompleted();
})
};
this.Control.InputAccessoryView = toolbar;
}
I've searched up and down the internet throughout the day, and I'm just stumped.
What I want to do is play a youtube video inside of C# using the youtube API. Then I want a function on the form to be called when the video finishes playing. Unfortunately, I can't seem to find a way to get the events to fire.
(Using Visual C# 2010 Express, and have IE9. For reference.)
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
using System.Runtime.InteropServices;
public partial class Form1 : Form
{
// This nested class must be ComVisible for the JavaScript to be able to call it.
[ComVisible(true)]
public class ScriptManager
{
// Variable to store the form of type Form1.
private Form1 mForm;
// Constructor.
public ScriptManager(Form1 form)
{
// Save the form so it can be referenced later.
mForm = form;
}
// This method can be called from JavaScript.
public void MethodToCallFromScript()
{
// Call a method on the form.
mForm.GoToNext();
}
}
public Form1()
{
InitializeComponent();
}
public void GoToNext()
{
MessageBox.Show("Play the next song");
}
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.Navigate("http://localhost/index.html");
}
}
}
That is my Form1.cs code. Form1.cs [Design] consists of nothing more than a webBrowser control.
I've tried numerous things to get this to work, from installing an http server to run the html 'live' to running it from a file directly off my computer, to setting the document text with the code as a string. All has failed me thus far. In IE9 if I open the index.html file locally (as a file and not through my webserver) the events do not fire. If I run it live off my webserver the events do fire. However in C# webBrowser control, these events do not seem to fire at all, no matter where it's run from.
<!DOCTYPE html>
<html>
<body>
<div id="player"></div>
<script>
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
playerVars: { 'autoplay': 1, 'controls': 1,'autohide':1,'wmode':'opaque' },
videoId: 'G4cRrOcDXXY',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
event.target.mute();
}
function onPlayerStateChange(event) {
if(event.data === 0) {
alert('done');
window.external.MethodToCallFromScript();
}
}
</script>
</body>
</html>
I'm out of ideas, so any help would be greatly appreciated. I'd love to get events to fire in the C# WebBrowser control.
Wow. I was in the process of typing out my newest problem when I attempted something else with great success. The problem was that I'd navigate to my .html file on my webserver, and it'd begin playing a video, when the video finished, I'd have javascript tell C# to navigate to the same URL with a different youtube ID (to play another video). The second video would fail to fire the events.
I've overcome this by using different javascript, such as what was mentioned here.
I did start using Visual Studio 2013 Express, and IE11. That cleared up quite a few problems I was bumping into on it's own. I'll provide you guys with my current code, just in case anyone ever runs into the issues I've been dealing with.
My form:
using System;
using System.Windows.Forms;
using System.Data.SQLite;
namespace WindowsFormsApplication1
{
using System.Runtime.InteropServices;
public partial class Form1 : Form
{
// This nested class must be ComVisible for the JavaScript to be able to call it.
[ComVisible(true)]
public class ScriptManager
{
// Variable to store the form of type Form1.
private Form1 mForm;
// Constructor.
public ScriptManager(Form1 form)
{
// Save the form so it can be referenced later.
mForm = form;
}
public void AnotherMethod(string message)
{
mForm.GoToNext();
}
}
public Form1()
{
InitializeComponent();
}
public void GoToNext()
{
timer1.Interval = 2000;
timer1.Enabled = true;
}
public object MyInvokeScript(string name, params object[] args)
{
return webBrowser1.Document.InvokeScript(name, args);
}
public void SongCheck()
{
// Disable timer. Enable it later if there isn't a song to play.
if (timer1.Enabled)
timer1.Enabled = false;
// Connect to my SQLite db,
SQLiteConnection mySQLite = new SQLiteConnection("Data Source=ytsongrequest.s3db;Version=3;");
mySQLite.Open();
// The SQLite DB consists of three columns. id, youtubeid, requestor
// the 'id' auto increments when a row is added into the database.
string sqlCommand = "select * from songs order by id asc limit 1";
SQLiteCommand x = new SQLiteCommand(sqlCommand, mySQLite);
SQLiteDataReader reader = x.ExecuteReader();
if (reader.HasRows) {
while (reader.Read())
{
// Use our custom object to call a javascript function on our webpage.
object o = MyInvokeScript("createPlayerAndPlayVideo", reader["youtubeid"]);
label2.Text = reader["requestor"].ToString();
// Since we've played the song, we can now remove it.
x = new SQLiteCommand("delete from songs where id = " + reader["id"], mySQLite);
x.ExecuteNonQuery();
}
mySQLite.Close();
}
else
{
// Set a timer to check for a new song every 10 seconds.
timer1.Interval = 10000;
timer1.Enabled = true;
}
}
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.ObjectForScripting = new ScriptManager(this);
webBrowser1.Navigate("http://localhost/testing.html");
GoToNext();
}
private void timer1_Tick(object sender, EventArgs e)
{
SongCheck();
}
}
}
My HTML page that I have on my server:
<!DOCTYPE html>
<html>
<body>
<div id="player"></div>
<script>
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var query = getQueryParams(document.location.search);
var player;
var playerAPIReady;
function onYouTubePlayerAPIReady() {
playerAPIReady = true;
}
function onPlayerReady() {
player.playVideo();
player.addEventListener('onStateChange', function(e) {
if (e.data === 0) {
window.external.AnotherMethod('Finished video');
}
});
}
function getQueryParams(qs) {
qs = qs.split("+").join(" ");
var params = {}, tokens,
re = /[?&]?([^=]+)=([^&]*)/g;
while (tokens = re.exec(qs)) {
params[decodeURIComponent(tokens[1])]
= decodeURIComponent(tokens[2]);
}
return params;
}
function createPlayerAndPlayVideo(id) {
if(! playerAPIReady) {
// player API file not loaded
return;
}
if (! player) {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: id,
events: {
'onReady': onPlayerReady
}
});
}
else {
player.loadVideoById(id);
}
}
</script>
</body>
</html>
I've setup a web site to be localized using Global resources only. I'm having a hard time figuring out why a page is always giving inconsistent behavior every time I trigger a culture change through a drop down list. Here are my resource files:
Resources:
Setup
Here is the Base Page that is inherited by all pages:
public partial class BaseWebForm : Page
{
protected override void InitializeCulture()
{
if (Session["UserLanguage"] != null)
{
String selectedLanguage = Session["UserLanguage"].ToString();
UICulture = selectedLanguage;
Culture = selectedLanguage;
CultureInfo culture = CultureInfo.CreateSpecificCulture(selectedLanguage);
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
}
base.InitializeCulture();
}
}
I'm using a Session variable, UserLanguage, to manage selected language. My site assumes en-US as default language and the drop down is displayed on the login page. That means the user cannot change language on any page as, upon login page, a service retrieves available languages.
I'm using Master page and I've handled the menus, breadcrumb SiteMapPath, and LTR-RTL there.
On the actual page, here is a brief:
public partial class PublicLogOn : BaseWebForm
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (Request.IsAuthenticated)
{
SiteLogger.NLogger.Info("Request Authenticated");
SiteLogin.RedirectToDefaultPage();
}
#region Handle Return URL
if (HttpContext.Current.Request.QueryString["ReturnUrl"] != null && !String.IsNullOrEmpty(HttpContext.Current.Request.QueryString["ReturnUrl"]))
{
var tempUrl = HttpContext.Current.Request.QueryString["ReturnUrl"];
SiteLogger.NLogger.Info("Return URL : " + tempUrl);
if (tempUrl.Contains(#"/SecuredArea/AdminArea/"))
{
buttonLogOn.Visible = false;
// buttonAdminLogOn.Visible = true;
}
else if (tempUrl.Contains(#"/SecuredArea/EmployeeArea/"))
{
buttonLogOn.Visible = true;
// buttonAdminLogOn.Visible = false;
}
else
{
// buttonLogOn.Visible = buttonAdminLogOn.Visible = true;
buttonLogOn.Visible = true;
}
}
#endregion
if (!Page.IsPostBack)
{
SiteLogger.NLogger.Info("Loading Languages and Directories");
// Actual language loading
if (!LoadLanguages() || !LoadDirectories())
{
SiteLogger.NLogger.Info("Loading Languages or Directories failed!");
return;
}
SiteLogger.NLogger.Info("Completed : PublicLogOn.PageLoad");
}
// Don't know why this fails and the drop-down still shows en-US even culture is ur-PK
//if (Session["UserLanguage"] != null)
//{
// DDLLanguages.SelectedValue = Session["UserLanguage"].ToString();
//}
}
catch (Exception ex)
{
SiteLogger.NLogger.Error("Error in PublicLogOn.Page_Load", ex.Message);
}
}
private Boolean LoadLanguages()
{
Boolean methodResult;
try
{
SiteLogger.NLogger.Info("In Load Languages");
// This line also mess up
// Session["UserLanguage"] = null;
DDLLanguages.Items.Clear();
var fetchedLanguages = UserManagePage.GetOrganizationLanguages();
foreach (var oneFetchedLanguage in fetchedLanguages)
{
DDLLanguages.Items.Add(new ListItem(oneFetchedLanguage.LanguageSymbol, oneFetchedLanguage.LanguageSymbol));
}
if (fetchedLanguages.Count() == 1)
{
DDLLanguages.Enabled = false;
}
methodResult = true;
}
catch (Exception exp)
{
SiteLogger.NLogger.Error("Error in load languages : ", exp.ToString());
labelMessage.Text = MessageFormatter.GetFormattedErrorMessage("Error retrieving organization languages.");
methodResult = false;
}
return methodResult;
}
private Boolean LoadDirectories()
{
// Nothing to-do with code-in-question
}
protected void ButtonLogOn_Click(object sender, EventArgs e)
{
// Nothing to-do with code-in-question
}
protected void DDLLanguages_SelectedIndexChanged(object sender, EventArgs e)
{
Session["UserLanguage"] = DDLLanguages.SelectedValue;
// Reload-hack. Was recommended on SO.
Response.Redirect(Request.Url.AbsolutePath);
}
}
After all of this, there one more point where the session variable is used as read-only: I'm using a header to tell my server that the client's using xyz language and that server should return translated data, where applicable:
public class CustomInspectorBehavior : IClientMessageInspector, IEndpointBehavior
{
#region IClientMessageInspector
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
string languageIdentifier;
if (HttpContext.Current.Session["UserLanguage"] != null)
{
languageIdentifier = HttpContext.Current.Session["UserLanguage"].ToString();
}
else
{
languageIdentifier = CultureInfo.CurrentCulture.ToString();
}
var typedHeader = new MessageHeader<string>(languageIdentifier);
var untypedHeader = typedHeader.GetUntypedHeader("LanguageIdentifier", "");
request.Headers.Add(untypedHeader);
return null;
}
#endregion
#region IEndpointBehavior
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
var inspector = new CustomInspectorBehavior();
clientRuntime.MessageInspectors.Add(inspector);
}
#endregion
}
Results
Expected: I change the selected value on the drop-down and the page reload with new language + secure the selection in session. Now upon going to other pages, the new language is presented.
Actual: "LOL". I change the selected value from the default en-US to ur-PK and the web site updates to Urdu. All pages are in Urdu. I try to select en-US again and I realize I'm stuck with Urdu. The base page's InitializeCulture() trigger way too early and it finds Session["UserLanguage"] = ur-PK'. After that thePage_Loadof thePublicLogOnpage triggers effectively putting Drop down's selected value to still ur-PK. After thatDDLLanguages_SelectedIndexChangedof thePublicLogOn` page triggers updating the session variable to the selected value which is set to ur-PK from the recent PageLoad. Issue. The Hack triggers in the end repeating the cycle one more time.
I'm trying a number of things but end in this mini-loop. Any help will be appriciated.
You could do a redirect after your set the new language in the session.
I re-did the whole thing from scratch. Turns out there was one or two variables being static at IIS level which were the cause of all the pain.
I am developing a program which has an invisible web browser control that is used for loading data from certain web pages. However, I am having trouble blocking a certain type of popup.
This is the code I am currently using to block popups
private void webBrowser1_NewWindow( object sender,
System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
}
I have tested it on http://www.popuptest.com/ and it fails to block the Come & Go test and the Modeless Window test. http://i75.servimg.com/u/f75/13/13/40/49/b11.png
Is there a way to block these popups?
This is the javascript which shows the popups
function modelesswin(url,mwidth,mheight){
if (document.all&&window.print) //if ie5
eval('window.showModelessDialog(url,"","help:0;resizable:1;dialogWidth:'+mwidth+'px;dialogHeight:'+mheight+'px")')
else
eval('window.open(url,"","width='+mwidth+'px,height='+mheight+'px,resizable=1,scrollbars=1")')
}
modelesswin("http://www.popuptest.com/popup1.html",600,600)
Try implementing WebBrowser Feature Control, particularly FEATURE_BLOCK_INPUT_PROMPTS and FEATURE_WEBOC_POPUPMANAGEMENT.
[EDITED] This code works for me with your test site, try it (tested with IE10). Make sure you set features before your WebBrowser gets created (before InitializeComponent below) and you do ScriptErrorsSuppressed = true to suppress script errors caused by blocked pop-ups.
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
using Microsoft.Win32;
namespace WinformsWB
{
public partial class Form1 : Form
{
public Form1()
{
SetBrowserFeatureControl();
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.webBrowser1.ScriptErrorsSuppressed = true;
this.webBrowser1.Navigate("http://www.popuptest.com/");
}
private void SetBrowserFeatureControlKey(string feature, string appName, uint value)
{
using (var key = Registry.CurrentUser.CreateSubKey(
String.Concat(#"Software\Microsoft\Internet Explorer\Main\FeatureControl\", feature),
RegistryKeyPermissionCheck.ReadWriteSubTree))
{
key.SetValue(appName, (UInt32)value, RegistryValueKind.DWord);
}
}
private void SetBrowserFeatureControl()
{
// http://msdn.microsoft.com/en-us/library/ee330720(v=vs.85).aspx
// FeatureControl settings are per-process
var fileName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);
// make the control is not running inside Visual Studio Designer
if (String.Compare(fileName, "devenv.exe", true) == 0 || String.Compare(fileName, "XDesProc.exe", true) == 0)
return;
// TODO: FEATURE_BROWSER_MODE - what is it?
SetBrowserFeatureControlKey("FEATURE_BROWSER_EMULATION", fileName, 9000); // Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode.
SetBrowserFeatureControlKey("FEATURE_DISABLE_NAVIGATION_SOUNDS", fileName, 1);
SetBrowserFeatureControlKey("FEATURE_WEBOC_POPUPMANAGEMENT", fileName, 1);
SetBrowserFeatureControlKey("FEATURE_BLOCK_INPUT_PROMPTS", fileName, 1);
}
}
}