Using Javascript to disable a button in ASP.NET

How do we stop those trigger happy web users who feel the need to press buttons more than once. One way is to disable/change the button on the first click. All that is required is a couple of simple lines of code to make this happen. In my Page_Load event I have the following;

if (!IsPostBack)
{
    MyASPNetButton.Attributes.Add("onclick", "this.value='Please wait...'; this.disabled=true;" +      Page.ClientScript.GetPostBackEventReference(MyASPNetButton, "").ToString());
}

Silverlight/WPF Design Time data

Like all good things, its simple and straight forward. For more details take a look at this post

Solution – XamlParseException [Line : 0, Position 0] in Expression Blend Design Mode

Sometimes it just really helps to read the manual. This is a link to my post in the Expression Blend forum.

Retrieving parameters passed to WCF Async method

This useful tip came in very handy for me…

Silverlight and Session variables

I have seen numerous postings about how to access Session data from the current HttpContext using WCF. A simple example can be found here. Whilst looking for a solution to another Silverlight problem I came across this post about passing large text to SL using initParams and it got me thinking. Could I use the same concept to read my Session variables?

The short answer is Yes, with a few small changes. My initial problem was that my session variable contained a class of complex types. In order to serialize this I just need to mark the class as [Serializable]. I then set my initParams value:

<param name="InitParams" value="<%=InitParams%>" />

In the code behind for the page hosting the SL control I added:

protected string InitParams { get; private set; }

Then I just needed to convert my Session variable to a Base64 string during the Page_Load event.

MemoryStream stream = new MemoryStream();
XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
serializer.Serialize(stream, <my session variable> );       // Of type MyClass
stream.Position = 0;
string data = Convert.ToBase64String(stream.ToArray());
InitParams = "SessionDetails=" + data;

In my Silverlight Page, I just had to do the reverse to get my class back from the Base64 string.

if (App.Current.Host.InitParams.ContainsKey("SessionDetails"))
{
    MemoryStream ms = new MemoryStream(Convert.FromBase64String(App.Current.Host.InitParams["SessionDetails"]));
    StreamReader sr = new StreamReader(ms);
    string s = sr.ReadToEnd();

    sr.Close();
    sr.Dispose();

    ms.Close();
    ms.Dispose();

    // Parse the string so we can determine the contents of the Session variable
    XElement xElement = XElement.Parse(s);
}

And that is about it. The only other thing that is required is a bit a LINQ to get to the necessary values within the Session variable. Obviously this only works if you need to read in the Session variables one time when the SL control loads, but for me this was perfectly suitable.

Converting Byte Arrays to Strings (C#)

It’s a lot easier than you think!
 
This is as much as a reminder to myslef as a helpful hint for other people. If you need to convert a byte array to a string the you can use the System.BitConverter class and the ToString() method which accepts a byte array as a parameter. For more information have a look at http://msdn.microsoft.com/en-us/library/system.bitconverter.aspx 
 
I used this for debugging SQL Server Timestamp columns so that I could get a more readable version of the column contents.

Accessing other resource files in your web application

Using GetLocalResourceObject() to access resource files from other resource objects.
 
I have been doing some work on localising (localizing…no pun intended) a website. One of the issues I have found is that there may be an occassion that I would want to access the resource key from other local resource objects. For example, I can use GetLocalResourceObject("resourceKey1.Text") to get a text value for the current ASPX page that I am working on. I can also use the HttpContext class to access the same resource keys by specifiying HttpContext.GetLocalResourceObject(Page.AppRelativeVirtualPath, "resourceKey1.Text");
 
So, this got me thinking. Can I do the same think to access resource keys for another page using the same method? The answer is, Yes. I just need to replace the Page.AppRelativeVirtualPath with a virtual path to the page I am interested in and look for the relevant resource key in the resource file. For example, HttpContext.GetLocalResourceObject("~/MyFolder/MyPage.aspx", "resourceKey2.Text" ); will find the entry for resourceKey2.Text in the resource file MyPage.aspx.resx in the App_LocalResources folder.

System.MissingMethodException

Method not found: ‘System.Web.UI.IDataSource System.Web.UI.WebControls.DataBoundControl.get_DataSourceObject()’.
 
I got the error above when calling the IPostBackEventHandler.RaisePostBackEvent on a web page running on a server used for testing. Since it wasn’t occuring on any of the development machines then simple logic meant there had to be a difference in the assemblies residing on the server. In this case it was the version of the .Net Framework 3.5 as the server had not had SP 1 installed. Once the machine had been updated the problem was resolved.

Default Resource Files in Assemblies

How do I access string resources in the default resource file for an assembly? 
 
Accessing strings in a resource file for a web application is fairly straight forward using GetLocalResourceObject and GetGlobalResourceObject. Since the web application that I am currently writing uses additional assemblies I needed a way to localise some of the string values stored in these files. Obviously, I can add individual resource files to this separate assembly and access then using the ResourceManager. One of the articles I read about this included this one http://www.codeproject.com/KB/cs/cs-multi-assembly-res.aspx.
 
My issue was that I didn’t know how to access the content when adding a default resource file. The default resource file is generated when you view the Properties of an assembly and select the Resources tab. If you have not already created a default resource fle you will see the message This project does not contain a default resource file. Click here to create one.  Once you have selected this option and created the default file, the question is how to I get to the content stored in it?
 
The answer is from the resource manager but ensuring you specify the full baseName parameter for the ResourceManager constructor. For example, if I have an assembly with an Assembly Name of MyAssembly.SomeNamespace and have created a default resource file called Resources.resx then I can access a string resource in the default resource file using the following code;
 

ResourceManager rm = new ResourceManager("MyAssembly.SomeNamespce.Properties.Resources", Assembly.GetExecutingAssembly());

string

myString = rm.GetString("MyStringResource");

This is because the default resource file resides under the Properties folder of the satellite assembly. Details about the resource manager can be found here http://msdn.microsoft.com/en-us/library/system.resources.resourcemanager.aspx