I recently upgraded a website from asp.net 1.1 to asp.net 2.0 "web application project"
Everything worked fine except for one small page that just wouldn't run, The first line of the aspx file reported an "ambigous match" error, and when I ran the page the same error cropped up.
It turns out that the culprit was a textbox that was defined two times in the codebehind:
protected TextBox txtPostNumber
protected TextBox txtPostnumber
with the only difference being in the casing.
Althought this clearly is fishy code, the second textbox was never used, so no harm done right?
well ASP.NET 1.1 handles this like you would expect, ignoring the other textbox.
ASP.NET 2.0 on the other hand gave me the before mentioned cryptic "ambigous match" error. It turns out that ASP.NET 2.0 acts case-insensitively in this regard.
I wonder why they changed it, and why they can't give a more useful error message...
Wednesday, December 20, 2006
Friday, August 18, 2006
Textbox submit on enter
In .net 1.1, getting a textbox to submit on enter pressed is easy,
Put in the textbox (we'll call it UserPassword here) on the form (runat="server") and declare it in the codebehind with the same ID)
Have a submit button, either of type <asp:Button id="BtnSubmit" runat="server"../> or <input id="BtnSubmit" runat="server"...> on the form,
declare a variable in the codebehind with the same ID as the button or input and of the same type (Button or HtmlInputButton)
Wire the submit button up to do the actual submitting and then in Page_Init or Page_Load write this line of code (13 is the magical number for the enter key)
UserPassword.Attributes.Add("onkeydown", "if(event.which || event.keyCode){if ((event.which == 13) || (event.keyCode == 13)) {document.getElementById('"+BtnSubmit.UniqueID+"').click();return false;}} else {return true}; ");
and there you have it
Put in the textbox (we'll call it UserPassword here) on the form (runat="server") and declare it in the codebehind with the same ID)
Have a submit button, either of type <asp:Button id="BtnSubmit" runat="server"../> or <input id="BtnSubmit" runat="server"...> on the form,
declare a variable in the codebehind with the same ID as the button or input and of the same type (Button or HtmlInputButton)
Wire the submit button up to do the actual submitting and then in Page_Init or Page_Load write this line of code (13 is the magical number for the enter key)
UserPassword.Attributes.Add("onkeydown", "if(event.which || event.keyCode){if ((event.which == 13) || (event.keyCode == 13)) {document.getElementById('"+BtnSubmit.UniqueID+"').click();return false;}} else {return true}; ");
and there you have it
Thursday, June 22, 2006
String to Enum C#
I found this little snippet on a blog by Mark Wagner's blog,
and already this baby has saved me quite a bit of work, so I thought I'd post it also, btw. Marks blog can be found here
Convert a string to an enumerated (enum) value.
Using the Enum.Parse method, you can easily convert a string value to an enumerated value. Doing this requires the type of the enum and string value. Adding the true argument will cause the case to be ignored.
Using the following enum for this example:
private enum Aircraft
{
Beech,
Cessna,
Piper
}
You can easily convert the string to an enum value like this:
Aircraft air = (Aircraft) Enum.Parse(typeof(Aircraft), "Cessna", true);
Ideally you should wrap a try-catch around the Enum.Parse statement.
and already this baby has saved me quite a bit of work, so I thought I'd post it also, btw. Marks blog can be found here
Convert a string to an enumerated (enum) value.
Using the Enum.Parse method, you can easily convert a string value to an enumerated value. Doing this requires the type of the enum and string value. Adding the true argument will cause the case to be ignored.
Using the following enum for this example:
private enum Aircraft
{
Beech,
Cessna,
Piper
}
You can easily convert the string to an enum value like this:
Aircraft air = (Aircraft) Enum.Parse(typeof(Aircraft), "Cessna", true);
Ideally you should wrap a try-catch around the Enum.Parse statement.
Saturday, May 27, 2006
watching for changes in webapps
Recently I came across code in a project that had been built to check for changes in order to give the user warnings like "remember to save.." "do you really want to navigate away.." etc. As this project uses Typed datasets for all they're worth (which is quite a lot as long as the complexity of the domain is easily managed) the actual check for changes was done through calling the datasets ToXml() method and holding that string in the session and constantly check against that as the user went about his business.
Now, this project had in NO way a stateless web server, but then the requirements didn't call for that either, but still. each dataset (of which the user would typically have 1-20 of within a session) was saved in the session and also its xml was saved (to perform change-watching).
Thw problem was that although there were few users (<10), the xml for each dataset had a footprint of about 1.6 MB each.
So what did I do to ease the pain? I changed the code to check and save not the raw xml, but a hash of the xml. To do this I made one small method that translated from string to a hashed string, All up I spent about 20 minutes implementing and testing this schema and the estimated footprint-savings is in the area of 150 MB of server memory.
so what about the code eh? well here it is:
public static string ComputeHashFromString(string message, HashAlgorithm ha)
{
byte[] msgbytes = ASCIIEncoding.ASCII.GetBytes(message);
byte[] hashBytes = ha.ComputeHash(msgbytes);
StringBuilder sb = new StringBuilder();
foreach(byte b in hashBytes)
{
sb.Append(b.ToString("x2"));
}
return sb.ToString();
}
public static string ComputeHashFromString(string message)
{
return ComputeHashFromString(message, new MD5CryptoServiceProvider());
}
Now, this project had in NO way a stateless web server, but then the requirements didn't call for that either, but still. each dataset (of which the user would typically have 1-20 of within a session) was saved in the session and also its xml was saved (to perform change-watching).
Thw problem was that although there were few users (<10), the xml for each dataset had a footprint of about 1.6 MB each.
So what did I do to ease the pain? I changed the code to check and save not the raw xml, but a hash of the xml. To do this I made one small method that translated from string to a hashed string, All up I spent about 20 minutes implementing and testing this schema and the estimated footprint-savings is in the area of 150 MB of server memory.
so what about the code eh? well here it is:
public static string ComputeHashFromString(string message, HashAlgorithm ha)
{
byte[] msgbytes = ASCIIEncoding.ASCII.GetBytes(message);
byte[] hashBytes = ha.ComputeHash(msgbytes);
StringBuilder sb = new StringBuilder();
foreach(byte b in hashBytes)
{
sb.Append(b.ToString("x2"));
}
return sb.ToString();
}
public static string ComputeHashFromString(string message)
{
return ComputeHashFromString(message, new MD5CryptoServiceProvider());
}
Tuesday, May 16, 2006
Making Custom Properties aware of their context in EPiServer
What you might want to do inside a custom property is to check the value of some other properties in the current page. What you will notice is that Custom Properties are not aware of the CurrentPage, in order to fetch it you will need to override the
InitializeData method that the base class of all EPiServer properties has.
You can get the pagereference within that method
PageReference _pageLink;
public override void InitializeData(EPiServer.ApplicationConfiguration config,PropertyDataCollection properties)
{
PropertyPageReference pageLinkProperty = properties["PageLink"] as PropertyPageReference;
if (!pageLinkProperty.IsNull) { _pageLink = pageLinkProperty.PageLink;}
base.InitializeData(config, properties);
}
InitializeData method that the base class of all EPiServer properties has.
You can get the pagereference within that method
PageReference _pageLink;
public override void InitializeData(EPiServer.ApplicationConfiguration config,PropertyDataCollection properties)
{
PropertyPageReference pageLinkProperty = properties["PageLink"] as PropertyPageReference;
if (!pageLinkProperty.IsNull) { _pageLink = pageLinkProperty.PageLink;}
base.InitializeData(config, properties);
}
Wednesday, April 26, 2006
Report Server: The report server cannot decrypt the symmetric key
If you ever come across this error message in SQL Server 2000 Report Server, it is usually caused by one of two things. Either you have recently changed the account that is used to run the ReportServer service, in which case you should follow this article:
http://support.microsoft.com/kb/842421
or you installed or uninstalled some part of .net 2.0 recently, in which case you might have to run the rsactivate tool. go to the directory:
C:\Program Files\Microsoft SQL Server\MSSQL\Reporting
Services\ReportServer\
or the equivalent program path on your computer and type
rsactivate -r -c RSReportServer.config
if rsactivate is not in your path (which it should be after an install) you will find it in
C:\Program Files\Microsoft SQL Server\80\Tools\Binn
or whatever path is the equivalent on your machine
http://support.microsoft.com/kb/842421
or you installed or uninstalled some part of .net 2.0 recently, in which case you might have to run the rsactivate tool. go to the directory:
C:\Program Files\Microsoft SQL Server\MSSQL\Reporting
Services\ReportServer\
or the equivalent program path on your computer and type
rsactivate -r -c RSReportServer.config
if rsactivate is not in your path (which it should be after an install) you will find it in
C:\Program Files\Microsoft SQL Server\80\Tools\Binn
or whatever path is the equivalent on your machine
Wednesday, March 22, 2006
Thinking Ruby in C# 2.0 ?
foreach(string chosenstring in myList.FindAll(new Predicate<string>(delegate(string s)
{
return s.Length>10;
})))
{
Console.WriteLine("the following string is long: " +chosenstring);
}
The preceding code will run through a list containing strings and output the strings longer than 10 words.
read it and weep
{
return s.Length>10;
})))
{
Console.WriteLine("the following string is long: " +chosenstring);
}
The preceding code will run through a list containing strings and output the strings longer than 10 words.
read it and weep
Friday, March 03, 2006
Setting asp:Label texts too early
Just discovered that if you have method calls to the code-behind (typically a protected method in the codebehind called between <% %> tags) You cannot alter The text property on labels in that method.
This probably extends to manipulating any property on any webcontrol defined in the code-front. I guess it's just too early.
when stepping through the code The label had its original value (which obviously would have been read/instantiated in the code-front), I replaced it with a new value and when the page rendered it had turned back to the original value.
I guess this means that the code-front is read twice, before method calls in it are handled, and after. Is it just me that find this weird?
The fix to my problem was easy, I just placed the method-call in Page_Load, so no biggie, but I was stumped on it for a while
Edit: OK, so I might have missed the obvious, but of course the ViewState is copied back.. and overwrites my changes. Since ViewState is copied just before Page_Load, The earliest you can write to weeb-controls is page_load
This probably extends to manipulating any property on any webcontrol defined in the code-front. I guess it's just too early.
when stepping through the code The label had its original value (which obviously would have been read/instantiated in the code-front), I replaced it with a new value and when the page rendered it had turned back to the original value.
I guess this means that the code-front is read twice, before method calls in it are handled, and after. Is it just me that find this weird?
The fix to my problem was easy, I just placed the method-call in Page_Load, so no biggie, but I was stumped on it for a while
Edit: OK, so I might have missed the obvious, but of course the ViewState is copied back.. and overwrites my changes. Since ViewState is copied just before Page_Load, The earliest you can write to weeb-controls is page_load
Sunday, February 26, 2006
VS2003: "unable to read the project file" "the system cannot find the file specified"
OK, so I've had this nuissance for a week before I finally snapped and had to fix it: Every time I started Visual Studio and opened up my project I would get an error message saying something to the effect of "unable to read the project file" "the system cannot find the file specified"...
The web project would not be loaded, only be displayed as "unavailable" and any project with bindings to the web project (IE. the test project) would lose their bindings.
The drill would be to delete the unavailable project and add it anew through file -> add project -> from file. This would then fix the problem temporarily, except I would need to set the lost bindings again.
If I tried to add the project from web I would get the error message stated above.
So how does one solve such a predicament?
Exit VS,
Delete the .SUO file
Start VS
Set the source control that you lost
Done, enjoy error free heaven
The web project would not be loaded, only be displayed as "unavailable" and any project with bindings to the web project (IE. the test project) would lose their bindings.
The drill would be to delete the unavailable project and add it anew through file -> add project -> from file. This would then fix the problem temporarily, except I would need to set the lost bindings again.
If I tried to add the project from web I would get the error message stated above.
So how does one solve such a predicament?
Exit VS,
Delete the .SUO file
Start VS
Set the source control that you lost
Done, enjoy error free heaven
Thursday, January 05, 2006
OK so I blew it
I ran out of steam mid-december, I tried to find other stuff i wanted to share with the world of programmers out there, I really really had heaps of stuff to do at work. and suddenly I needed to get xmas prezzies for everyone... jeez get off my back will you?
Basicly I figured out that instead of writing twelve more posts that weren't interesting I'd take some time out and figure out new stuff to write about so that the quality of the blog wouldn't plummet.
To all would-be christmas calendar writers out there: do yourselves a favor, have the calendar ready before december, coz december isn't as slow and easy as one would like to think.
So instead of sweating it, I'll write when I want about what I want.
So there
Basicly I figured out that instead of writing twelve more posts that weren't interesting I'd take some time out and figure out new stuff to write about so that the quality of the blog wouldn't plummet.
To all would-be christmas calendar writers out there: do yourselves a favor, have the calendar ready before december, coz december isn't as slow and easy as one would like to think.
So instead of sweating it, I'll write when I want about what I want.
So there
Subscribe to:
Posts (Atom)