In the recent project I've been working on we were running into 2 issues related to the URLs: first we have links all over on the pages which link to each other, if we rename a page or move it to a different folder, we need to change every place where links to this page. Secondly, we have couple pages that need to be secured (i.e. https is needed). but all the urls on the site are relative (which is good), so once user is redirected to the secure page, he will stay on secure pages because all the links on the page start with https.
An ideal solution would be:
(1) all the urls of the site should be saved in a config file (xml formatted) or resource file
(2) create a custom control to generate <a> tag. which we can put more properties like (bool)IsSecure,
Tuesday, December 04, 2007
Wednesday, November 21, 2007
Reference variable in Applicate State
Most of us might think that when you save something to session, cache or other application state, ASP.NET save a copy of the variable to it. Take a cache for example, if you save a integer like this, we all know the cache value won't change
However, if you save a reference value, the cache object value changes as the reference object changes in the memory. like the exampel below the tc object in the cache is also changed when the tc in the memory changes. the Number property becomes 2.
Another thing we should be aware of is: if you set the tc to null (tc=null), the object is still there in cache. This is because the tc=null state just breaks the reference of the tc and object allocated in the heap memory. so conside the following example, the Number property of the object in the cache is still 1 even if the tc.Number set to 2 later.
1: int i = 1;
2: Cache["Number"] = i;
3: i++;4: //Cache["Number"] will still be 1
However, if you save a reference value, the cache object value changes as the reference object changes in the memory. like the exampel below the tc object in the cache is also changed when the tc in the memory changes. the Number property becomes 2.
private void TestCache()
{
TestClass tc;
if (Cache["TestClass"] != null)
tc = Cache["TestClass"] as TestClass;
else
{
tc = new TestClass();
Cache["TestClass"] = tc;
}
tc.Number = 2;
}
public class TestClass
{
public int Number = 0;
}
Another thing we should be aware of is: if you set the tc to null (tc=null), the object is still there in cache. This is because the tc=null state just breaks the reference of the tc and object allocated in the heap memory. so conside the following example, the Number property of the object in the cache is still 1 even if the tc.Number set to 2 later.
private void TestCache()
{
TestClass tc;
if (Cache["TestClass"] != null)
tc = Cache["TestClass"] as TestClass;
else
{
tc = new TestClass();
Cache["TestClass"] = tc;
}
tc = new TestClass();
tc.Number = 2;
}
Wednesday, October 24, 2007
Relative path and menu highlight
One of the beatiful thing about Asp.Net is you can use ~ to make a relative path, and .NET will figure out the full path at the run time no matter what environment the application sits on. (For example, your app might not be on the root folder on the QA box as it in production). If you use .NET built-in menu the highlight functions is alreay there. meaning the a menu item can be highlighted if you are on this target page. However, if you are building a menu by yourself, you have to implement it by yourself, and this is how you can do it:
(1) in the menu source file, normally a xml file, you put the app relative path with ~ in it, for example use ~/myfolder/mypage.aspx instead of /myfolder/mypage.aspx
(2) in the load event of the menu control, whether custom or user control, check the if current Page.AppRelVirtualPath is equal to a particular menu item, if so highlight that menu item
that's it
(1) in the menu source file, normally a xml file, you put the app relative path with ~ in it, for example use ~/myfolder/mypage.aspx instead of /myfolder/mypage.aspx
(2) in the load event of the menu control, whether custom or user control, check the if current Page.AppRelVirtualPath is equal to a particular menu item, if so highlight that menu item
that's it
Thursday, August 30, 2007
efficient way to reload database
I have to reload a huge database by a program regularily. There are two datasources for this database, but there are some user inputed information in the database too, like comments. here are some experiences I gain from doing this:
(1) selected the user inputed information into a hashtable or arraylist with database primary key, a simple struct or class will serve the purpose
(2) in database table, have backup indicator column, when insert, only insert as backup data
(3) keep count the error rate when inserting
(4) at the end, if everything is fine, error rate is low, delete the no-backup data and flipover backup data to live
(5) make sure all queries to the database only get live data, not backup data. Or to create a view for this
(1) selected the user inputed information into a hashtable or arraylist with database primary key, a simple struct or class will serve the purpose
(2) in database table, have backup indicator column, when insert, only insert as backup data
(3) keep count the error rate when inserting
(4) at the end, if everything is fine, error rate is low, delete the no-backup data and flipover backup data to live
(5) make sure all queries to the database only get live data, not backup data. Or to create a view for this
Search dataset/dataview using primary key
If you have a huge dataset, the performance of searching a record using dataset.Select won't be efficient. The best way to do this is to make primary key(s) of the dataset/dateview.
following line add two primary keys to the dataview
DataView dv = new DataView(dt,null,"pol_nbr,pol_sfx",DataViewRowState.CurrentRows);
then you can search a row by these keys
following line add two primary keys to the dataview
DataView dv = new DataView(dt,null,"pol_nbr,pol_sfx",DataViewRowState.CurrentRows);
then you can search a row by these keys
object[] keys = new object[2];
keys[0] = "0000"+p.Number;
keys[1] = p.Suffix;
DataRowView[] drv = dv.FindRows(keys);
Simply Ajax Solution
No need any AJAX framework or fancy update panels, just by using some simple javascript you can get some cool Ajax effect, plus web service is not needed.
In this function, xmlHttp.onreadystatechange set a callback function, while xmlHttp.open("GET","slgetemail.aspx?pol=" + pol_nbr,true); initial the call of another page to get emails using a query string. So the whole content of the page will be parsed in the callback function and display the email.
function GetSLEmailByID(controlID, pol_nbr)
{
var xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttp.onreadystatechange=function()
{
if(xmlHttp.readyState==4)
{
try
{
document.getElementById(controlID).innerHTML = xmlHttp.responseText;
}
catch(e)
{
alert(controlID+"\n"+e.message);
}
}
}
xmlHttp.open("GET","slgetemail.aspx?pol=" + pol_nbr,true);
xmlHttp.send(null);
}
In this function, xmlHttp.onreadystatechange set a callback function, while xmlHttp.open("GET","slgetemail.aspx?pol=" + pol_nbr,true); initial the call of another page to get emails using a query string. So the whole content of the page will be parsed in the callback function and display the email.
Business layer sorting
Sometime, you need to sort a list of business object, for example you have a list of SLPolicy object in an arraylist, and you want to sort it in different ways, like by policynumber, expiration date, or agent code. You want to do this as easy as this:
ArrayList Policies = CreateListofPolicies() ;
SLPolicy.SortBy = "PolicyNumber";
Policies.Sort();
if that's what you want, you need to implement some class like below:
ArrayList Policies = CreateListofPolicies() ;
SLPolicy.SortBy = "PolicyNumber";
Policies.Sort();
if that's what you want, you need to implement some class like below:
[Serializable]
public class SLPolicy : IComparable
{
#region IComparable Members
public int CompareTo(object obj)
{
switch (_container.Container.SortKind)
{
case SLSortableKind.AgentCodeAsc:
return _agentCode.CompareTo(((SLPolicy) obj).AgentCode);
case SLSortableKind.AgentCodeDesc:
return ((SLPolicy) obj).AgentCode.CompareTo(_agentCode);
case SLSortableKind.InsuredNameAsc:
case SLSortableKind.InsuredNameDesc:
case SLSortableKind.ExpDateAsc:
return _expDate.CompareTo(((SLPolicy) obj).ExpDate);
case SLSortableKind.ExpDateDesc:
return ((SLPolicy) obj).ExpDate.CompareTo(_expDate);
default:
return 0;
}
}
#endregion
}
Crazy business requirements
I am going to organize all the good parts of the recent projects. But before that, I'd like to write down these nosense business requirements I've ever heard in this company. I believe it will fun to read them even couple years later.
(1) one business people asked if we can program the web application so that we can tell if customers are using keyboard or mouse, and if they are using keyboard, how fast they can type
(2) another business people wants to find out if user is visiting a page purposely or just accidentally click the wrong link.
(1) one business people asked if we can program the web application so that we can tell if customers are using keyboard or mouse, and if they are using keyboard, how fast they can type
(2) another business people wants to find out if user is visiting a page purposely or just accidentally click the wrong link.
Monday, July 09, 2007
Simple Ajax solution
We need to retrieve email address one by one through a MQ call for a report, (can you believe this?).
anyway, we don't want to hold our report for this, and there are still so many other informations besides email on the report. Therefore a Ajax solution is the best way to deal with this.
java script function:
anyway, we don't want to hold our report for this, and there are still so many other informations besides email on the report. Therefore a Ajax solution is the best way to deal with this.
java script function:
1: function GetSLEmailByID(controlID, pol_nbr) 2: { 3: //alert(controlID); 4: //document.getElementById(controlID).innerText = "updating ..."; 5: var xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); 6: xmlHttp.onreadystatechange=function() 7: { 8: if(xmlHttp.readyState==4) 9: { 10: try 11: { 12: document.getElementById(controlID).innerHTML = xmlHttp.responseText; 13: } 14: catch(e) 15: { 16: alert(controlID+"\n"+e.message); 17: } 18: } 19: } 20: xmlHttp.open("GET","slgetemail.aspx?pol=" + pol_nbr,true); 21: xmlHttp.send(null); 22: }
Subscribe to:
Posts (Atom)