In
one of my projects, I used Form Authentication to authenticate users
against our Intranet domain by using LDAP. The good things
are users
don't have to remember another pair of user name and password, and form
authentication gives users ability to log out. Users
cannot
log out if we use Windows Integrated Authentication.
By
design, if users click something which they don't have permission, form
authentication will automatically redirect them to the login page, and
there users can log in with another account to access the desired
resource. However in some use cases, users don't like this
behaviour. They argue that it's rare that users have 2
accounts
in the system. So if they don't have permission, we don't
have to
redirect them to the login page. We just need to display some
messages indicating they need an admin to reassign them the proper
permission. Here I just have a workaround when users are
redirected to the login page, I will display some information on the
login page to explain why they are showed the login page.
Another user requirement is users want to kill
the session and log out when the browser is shut down. This
requirement looks simple but It took me a long time to work on it.
Even worse is so far I haven't gotten the proper way to
resolve
the problem. But I did get some workarounds in this stage.
When
I searched from the internet, most people said you couldn't log out
automatically. This is true in that the session is stored in the
server, when users close the browser, the browser normally just closes
and won't send a message to the server. So the server never
knows
the client is already gone.
But when you go to some bank
websites, closing browser will log you out immediately. When
you
go to the same site again, the site always asks for your credentials.
I don't know how exactly they are doing. However, I
think
they might use their own login mechanism. Users are always
directed to the login page when users first open the website.
When login page opens, the website always clear the old
session
and old credentials, so users have to enter their account again.
Since in the middle, they won't be redirected to the login
page,
so this clearing won't bring trouble.
I referenced this
blog and this
discussion and this discussion
to implement my workaround.
First created the Exit.aspx page. In the page load method, do
the following:
protected void Page_Load(object sender,
EventArgs e)
{
FormsAuthentication.SignOut();
Session.Abandon();
// clear
authentication cookie
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,
"");
cookie.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(cookie);
FormsAuthentication.RedirectToLoginPage();
}
The
code kills the session and logs out the user. I put the code
in
the page load event handler so this page will never be displayed.
Then
in the normal pages add the following javascript code. Since
I
have a master page for all my pages, I can put this code in my master
page so every page will be affected.
<script type="text/javascript" >
var closeTab = false;
window.onbeforeunload =
checkBrowserBefore;
window.onunload = checkBrowserUnload;
function checkBrowserBefore() {
if (window.event.clientY <= 0) {
closeTab = true;
return "Do you leave the application or stay?";
}
else
closeTab = false;
}
function checkBrowserUnload() {
if (closeTab)
window.location.href = "../Exit.aspx";
}
</script>
Notice
here I check 2 events onbeforeunload and onunload. When users
close the browser tab or browser, the onbeforeunload will fire.
In IE a message box will pop up asking user to confirm the
closing. If user clicks Yes, or in some new IE versions users
choose Leave the page, the onunload will fire. Otherwise the
onunload will not fire. That's the reason we have to check
both
events.
Again we should remember this is just a workaround
and not guaranteed. This workaound only works in IE, but not
even in all
IE versions. In IE7, it works when users close either the IE
tab or the entire IE browser. But in IE9, it works when users
close
the IE tab, but not working when users close the IE browser.
I haven't tested on other IE versions or other browsers.
Also it is not working when users kill the browser process in task
manager or use Alt + F4 to close it.
Wednesday, October 24, 2012
Sunday, March 14, 2010
DevTeach 2010 Toronto
DevTeach 2010 Toronto is held in Microsoft headquarter in Mississauga on Mar 8-12. The main conference is from Mar 9 to Mar 11, plus one day pre conference workshop and one day post conference workshop. The main conference attendees are eligible for one year MSDN subscription. That is probably why so many people attended the conference.
Comparing to TechDays, the sessions in DevTeach are more advanced. These sessions cover architecture, agile, silverlight, sharepoint, and general web and Windows development. I took the main conference and pre conference workshop. I don't think the pre one deserves the cost ($400 one day). The Silverlight workshop I took only simply shows a series of sessions which we probably already knew in some previous Techdays sessions. Plus the organizing is not professional.
I like the main conference. The presenters impressing me include Michael Stiefel, Kimberly Tripp, Donald Belcham, etc. Some architecture sessions are very attractive, most of which are related with interface, layer, design pattern, design principle, and ORM. A couple of SQL sessions from Kimberly Tripp are outstanding. I also took some sessions which focus on particular fields, such as jQuery, LINQ, SharePoint, and Web farm.
It's beneficial and important to know what the people in the community are thinking and doing. When you listen to people, you can refresh your memory and probably come out some new ideas. I hope this conference experience can help improve our in-house WPF and Silverlight projects.
Comparing to TechDays, the sessions in DevTeach are more advanced. These sessions cover architecture, agile, silverlight, sharepoint, and general web and Windows development. I took the main conference and pre conference workshop. I don't think the pre one deserves the cost ($400 one day). The Silverlight workshop I took only simply shows a series of sessions which we probably already knew in some previous Techdays sessions. Plus the organizing is not professional.
I like the main conference. The presenters impressing me include Michael Stiefel, Kimberly Tripp, Donald Belcham, etc. Some architecture sessions are very attractive, most of which are related with interface, layer, design pattern, design principle, and ORM. A couple of SQL sessions from Kimberly Tripp are outstanding. I also took some sessions which focus on particular fields, such as jQuery, LINQ, SharePoint, and Web farm.
It's beneficial and important to know what the people in the community are thinking and doing. When you listen to people, you can refresh your memory and probably come out some new ideas. I hope this conference experience can help improve our in-house WPF and Silverlight projects.
Sunday, January 3, 2010
Silverlight and JavaScript interaction
In
Silverlight business applications, we may need to pass data to the
Silverlight control. If the volume of data is not
big, we can consider using Silverlight HTML Bridge to communicate
between JavaScript and Silverlight. This post summarizes how
to call JavaScript from Silverlight and vice versa.
Silverlight HTML Bridge is the technology that enables to call JavaScript from Silverlight managed code and call Silverlight managed code from JavaScript. The following example will use some simple code to demonstrate the 2 parts and point out some usual difficulties developers may encounter.
Call Silverlight from JavaScript
In the test.aspx file, I have the following form:
And I also have the following JavaScript in the same page:
In
Silverlight, the code-behind file contains the following code:
When users click the button on test.aspx page, the hidden text can be
passed to Silverlight.
Call JavaScript from Silverlight
In test.aspx, I added
In
Silverlight code-behind file, use HtmlPage to call the function:
Final Words
This is all the things related with how JavaScript and Silverlight interact. However, what I want to point out here is this convenient method may have some performance issues when you want to pass high volume of data to Silverlight. In my real project, I passed over 30 Mega pure data to Silverlight and I needed to parse the data, so the data needed over 10 seconds to be fully displayed. Some users may not want this experience. If that's the case, you may seek help from WCF to retrieve data in an asynchronous way.
Silverlight HTML Bridge is the technology that enables to call JavaScript from Silverlight managed code and call Silverlight managed code from JavaScript. The following example will use some simple code to demonstrate the 2 parts and point out some usual difficulties developers may encounter.
Call Silverlight from JavaScript
In the test.aspx file, I have the following form:
<form id="form1" runat="server"
style="height:100%;">
<asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager>
<div>
<input type="button" value="Start Silverlight" onclick="startSilverlight();" />
<input type="hidden" id="hiddenString" value="0.85,0.78,0.10,0.12,0.90" />
</div>
<div style="height:100%;">
<asp:Silverlight ID="Xaml1" Visible="true" runat="server" Source="~/ClientBin/SilverlightTest.xap" MinimumVersion="2.0.31005.0" Width="100%" Height="100%" />
</div>
</form>
<asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager>
<div>
<input type="button" value="Start Silverlight" onclick="startSilverlight();" />
<input type="hidden" id="hiddenString" value="0.85,0.78,0.10,0.12,0.90" />
</div>
<div style="height:100%;">
<asp:Silverlight ID="Xaml1" Visible="true" runat="server" Source="~/ClientBin/SilverlightTest.xap" MinimumVersion="2.0.31005.0" Width="100%" Height="100%" />
</div>
</form>
<script type="text/javascript"
language="javascript">
function startSilverlight() {
var plugin = document.getElementById("Xaml1");
if (plugin == null) {
alert("xaml1 is null");
return;
}
function startSilverlight() {
var plugin = document.getElementById("Xaml1");
if (plugin == null) {
alert("xaml1 is null");
return;
}
var
strControl = document.getElementById("hiddenString");
var str = strControl.value;
plugin.Content.Page.StartShow(str);
}
</script>
var str = strControl.value;
plugin.Content.Page.StartShow(str);
}
</script>
[ScriptableType]
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
HtmlPage.RegisterScriptableObject("Page", this);
}
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
HtmlPage.RegisterScriptableObject("Page", this);
}
[ScriptableMember]
public void StartShow(string data)
{
char[] charSeparators = { ',' };
string[] result;
result = data.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries);
float values[] = new float[result.Length];
public void StartShow(string data)
{
char[] charSeparators = { ',' };
string[] result;
result = data.Split(charSeparators, StringSplitOptions.RemoveEmptyEntries);
float values[] = new float[result.Length];
int i
= 0;
foreach (var str in result)
{
values[i++] = float.Parse(str);
}
foreach (var str in result)
{
values[i++] = float.Parse(str);
}
UpdateLayout(values);
}
}
}
}
Call JavaScript from Silverlight
In test.aspx, I added
<script type="text/javascript"
language="javascript">
function getSilverlightValue(text) {
alert(text);
}
</script>
function getSilverlightValue(text) {
alert(text);
}
</script>
HtmlPage.Window.Invoke("getSilverlightValue",
"A test string");
This is all the things related with how JavaScript and Silverlight interact. However, what I want to point out here is this convenient method may have some performance issues when you want to pass high volume of data to Silverlight. In my real project, I passed over 30 Mega pure data to Silverlight and I needed to parse the data, so the data needed over 10 seconds to be fully displayed. Some users may not want this experience. If that's the case, you may seek help from WCF to retrieve data in an asynchronous way.
Sunday, October 25, 2009
Set the DefaultFocus and DefaultButton in a master page
From ASP.NET 2.0 it is possible to set the default focus and default button with the DefaultFocus and DefaultButton properties which HtmlForm has. DefaultFocus sets which control to get the default focus in a form, and DefaultButton decides which button will fire the click event when users hit the enter key. In a page which uses a master page, you know the control name will be added a prefix string like ctl00_ContentPlaceHolder1_.
My example form has one EditBox named txtName and one Button named btnView. If I use the following code in the Page_Load event:
Page.Form.DefaultButton = btnView.ID;
or
Page.Form.DefaultButton = "btnView";
I get the following error:
The DefaultButton of 'form1' must be the ID of a control of type IButtonControl.
The reason is the control name is changed in a master page. So we have to use the following one in this case:
Page.Form.DefaultButton = btnView.UniqueID;
But for DefaultFocus, UniqueID seems not working for me. I have to use ClientID instead of UniqueID:
Page.Form.DefaultFocus = txtName.ClientID;
An alternative is use Focus() method. You could use the following to get the same effect as the above one:
txtName.Focus();
Sometimes you may want 2 or more default buttons on one page. This can be implemented by putting asp:Panel control around the controls. In the following example, when the cursor is in TextBox1, Button1 is the default button, otherwise when the cursor is in TextBox2, Button2 is the default button.
My example form has one EditBox named txtName and one Button named btnView. If I use the following code in the Page_Load event:
Page.Form.DefaultButton = btnView.ID;
or
Page.Form.DefaultButton = "btnView";
I get the following error:
The DefaultButton of 'form1' must be the ID of a control of type IButtonControl.
The reason is the control name is changed in a master page. So we have to use the following one in this case:
Page.Form.DefaultButton = btnView.UniqueID;
But for DefaultFocus, UniqueID seems not working for me. I have to use ClientID instead of UniqueID:
Page.Form.DefaultFocus = txtName.ClientID;
An alternative is use Focus() method. You could use the following to get the same effect as the above one:
txtName.Focus();
Sometimes you may want 2 or more default buttons on one page. This can be implemented by putting asp:Panel control around the controls. In the following example, when the cursor is in TextBox1, Button1 is the default button, otherwise when the cursor is in TextBox2, Button2 is the default button.
<asp:Panel ID="Panel1" DefaultButton="Button1" runat="server">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</asp:Panel>
<br />
<asp:Panel ID="Panel2" DefaultButton="Button2" runat="server">
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:Button ID="Button2" runat="server" Text="Button" onclick="Button2_Click" />
</asp:Panel>
Tuesday, October 13, 2009
Tech Days Toronto 2009
Tech Days Toronto came again. This year it was held one month early, on Sep. 29 and 30, 2009 at Metro Toronto Convention Centre, Downtown Toronto. It's said there were more people (1200 comparing to 1000 last year) attending the conference. It looks like the recession didn't affect companies' budget. :) I like the time and venue of this year. I didn't have to drive in the highway in the rush hour as last year. The time was one month earlier than last year, and Toronto was still warm.
Again this year all the presenters were from the partners of Microsoft, many of which had direct development and project experience. Several of them also presented in last year's Tech days. The good thing is the overall presentation skills of speakers are better than last year. In all 8 sessions (plus one bonus session) I attended, the speakers all had good presentation skills, and the materials were well prepared.
Let's talk about the sessions. In my opinion, this year is better than last year. Especially I like the added Developer Foundations track, which they said is coming from the feedback of many developers. This track was talking about some topics which could bring the developers to another level. One example was the five OO design principles. Of course we cannot expect too much from just 1 hour and 15 minutes (the total time of a session). The thing is you could get some ideas from other developers, and grasp a chance to practice in your own software development.
Except the Developer Foundations track, I mainly took some sessions for developers on Microsoft-based platform, such as Silverlight 3, Expression Blend for Developers and Prism. What I got from the sessions can be summarized as follows:
Again this year all the presenters were from the partners of Microsoft, many of which had direct development and project experience. Several of them also presented in last year's Tech days. The good thing is the overall presentation skills of speakers are better than last year. In all 8 sessions (plus one bonus session) I attended, the speakers all had good presentation skills, and the materials were well prepared.
Let's talk about the sessions. In my opinion, this year is better than last year. Especially I like the added Developer Foundations track, which they said is coming from the feedback of many developers. This track was talking about some topics which could bring the developers to another level. One example was the five OO design principles. Of course we cannot expect too much from just 1 hour and 15 minutes (the total time of a session). The thing is you could get some ideas from other developers, and grasp a chance to practice in your own software development.
Except the Developer Foundations track, I mainly took some sessions for developers on Microsoft-based platform, such as Silverlight 3, Expression Blend for Developers and Prism. What I got from the sessions can be summarized as follows:
- As Silverlight or WPF developers, we have to use Expression Blend in design time. It's impossible to write complex XAML tags in Visual Studio. Although developers usually don't like the design work, Expression Blend can save you tons of time when you need a complex XAML file, i.e. a multi-dimension animation.
- Silverlight 3 adds some new features, one of which is mouse wheel event support. Previously I created my own mouse wheel event handler. I need to check if the new features make the development easier.
- I heard several times about Prism and ASP.NET MVC, but I just don't know if they are practical and effective in real business projects. I will spend some time to investigate these frameworks and see if they can improve my projects.
- The best practise for developers is to get to know broadly any relative technologies. Some Java techniques could help .NET developers create a good design. Although I had experience in some other fields (except .net and c++) like Java, Mobile development, BI, I need some time to update my knowledge.
Subscribe to:
Posts (Atom)