Archive for November, 2009

25th Nov 2009

LocalMessageSender with strongly typed objects

If you need to have two Silverlight apps talking to each other, you would be using the LocalMessageSender and LocalMessageReceiver classes from the System.Windows.Messaging namespace. The LocalMessageSender class will only allow you to send string messages. So if you are looking to send strongly typed objects using the LocalMessageSender you will have to serialize the object and then deserialize it at the other end. I created a class which will do this work for you. I decided to use JSON as the serialization format because it is much more lightweight than Xml.

using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;

namespace Common
{
    public class JsonSerializer<T>
    {
        public static string Serialize(T objectToSerialize)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
                serializer.WriteObject(stream, objectToSerialize);
                stream.Position = 0;

                using (StreamReader reader = new StreamReader(stream))
                {
                    return reader.ReadToEnd();
                }
            }
        }

        public static T Deserialize(string jsonString)
        {
            using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
                return (T)serializer.ReadObject(stream);
            }
        }
    }
}

You can use this class like this

string serializedMsg = JsonSerializer<SimpleMessage>.Serialize(msg); 
SimpleMessage msg = JsonSerializer<SimpleMessage>.Deserialize(serializedMsg);

To give credit where it is due, I stole most of this code from here – http://www.silverlightshow.net/items/JSON-serialization-and-deserialization-in-Silverlight.aspx

Posted by Posted by pc under Filed under General Comments 2 Comments »

25th Nov 2009

LocalMessageSender with retry capability

If you need to have two Silverlight apps talking to each other, you would be using the LocalMessageSender and LocalMessageReceiver classes from the System.Windows.Messaging namespace. The problem with the LocalMessageSender is that it might not be able to send message at the very first try. So you will have to write code which retries to send the message for an x number of times. Rather than duplicating this code all over the place, I decided to create a class which will do this for you.

using System;
using System.Windows.Messaging;

namespace Common
{
    public class RetryMessageSender
    {
        private readonly int maxRetryCount;
        private LocalMessageSender messageSender;
        private int retryCount = 1;

        public event EventHandler<SendCompletedEventArgs> SendCompleted;

        public RetryMessageSender(LocalMessageSender messageSender)
            : this(messageSender, 100 /*default value of max retries*/)
        {
        }

        public RetryMessageSender(LocalMessageSender messageSender, int maxRetries)
        {
            this.messageSender = messageSender;
            this.maxRetryCount = maxRetries;
            messageSender.SendCompleted += new System.EventHandler<SendCompletedEventArgs>(messageSender_SendCompleted);
        }

        public void SendMessage(string msg)
        {
            messageSender.SendAsync(msg);
        }

        void messageSender_SendCompleted(object sender, SendCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                if (retryCount <= maxRetryCount)
                {
                    retryCount++;
                    SendMessage(e.Message);
                }
                else
                {
                    SendCompleted(sender, e);
                }
            }
            else
            {
                retryCount = 0;
                SendCompleted(sender, e);
            }
        }
    }
}

Now you can use this class like this:

RetryMessageSender msgSender = new RetryMessageSender(messageSender, 10);
msgSender.SendCompleted += new System.EventHandler<SendCompletedEventArgs>(msgSender_SendCompleted);
msgSender.SendMessage("hello");
In the SendCompleted event handler, you can check whether the message was sent successfully within the specified number of retries (10 in this case).
static void msgSender_SendCompleted(object sender, SendCompletedEventArgs e)
{
    if (e.Error != null)
    {
         throw new System.Exception("Unable to send message even after 10 retries");
    }
}

Posted by Posted by pc under Filed under General Comments 2 Comments »

20th Nov 2009

Duck Typing using C# 4.0

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            QuackTheQuacker(new Toy());
            QuackTheQuacker(new Duck());
        }

        static void QuackTheQuacker(dynamic quacker)
        {
            quacker.Quack();
        }
    }

    class Toy
    {
        public void Quack()
        {
            Console.WriteLine("A toy that quacks");
        }
    }

    class Duck
    {
        public void Quack()
        {
            Console.WriteLine("A duck that quacks");
        }
    }
}

Posted by Posted by pc under Filed under .NET, C# Comments No Comments »

14th Nov 2009

Blogging from iphone

I bought a new iPhone a few days ago and I am totally loving it. The only complaint that I have is the short battery time. If it could hold battery charge for a couple of days under heavy use, this would be the most perfect gadget I ever used. I am pretty sure Steve jobs have a few engineers working on it.

One of the things I like most about iPhone is the large number of neat apps available from the online store. I have always wanted to track my expenditures and i had made several attempts previously to do that using pen and paper as well as using a spreadsheet on a computer. The problem that I usually face is that I am not able to record transactions immediately. Usually I lose the receipt by the time I get to jot down the transaction or I just forget to do so. After a few attempts I just give up. With the iPhone I can immediately record the transaction using one of the many apps available to track expenses. I have already started using one.

Another good thing is the ability to tweet any time you want, assuming there is enough charge in the battery ;)

There is a wordpress app in the iPhone using which i am writing this post. I am waiting at the Lynnwood DOL with Rija for her knowledge test and I decided to make use of the time to write a blog post. The touch keyboard is a little too small for my liking but it is works well under the space constraints. I had difficulty in typing initially but now I my speed has improved quite well. People with thick thumbs might have a more difficult time. I think most apps have a landscape orientation which allows for wider keys and less typos.

Our number in the queue is getting closer so I will have leave you now, my dear reader, and go to the counter.

Have a nice day !

Posted by Posted by pc under Filed under Blog, iphone Comments No Comments »

06th Nov 2009

How to post source code on your blog

For a long time I have been looking for a tool to help me post source code on my blog. Obviously many people had solved this because we have all seen well formatted source code on many blogs. I did try several solutions including Syntax Highlighter, Copy Source as Html, C# code format from Manoli and even tried posting screen shots of the code (got this idea from Josh Smith’s blog). They didn’t work well for me (as you can see from several postings it did work for others, it is just a matter of personal taste). The screen shot idea is a good one except for the fact that the readers cannot copy the source from your blog and search engines cannot index the code. I had a workaround for this by linking to a text file which contained the source code. This made the process all mucky and cumbersome.

Some time in the recent past I stumbled on Live Writer. It was quite nifty and did a pretty good job with identifying your blog engine and templates and previewing your post. But when you copy pasted code from Visual Studio, it was not so pretty. Thankfully Douglas Stockwell had written a plugin for Live Writer to paste your code from Visual Studio. Together they did an amazing job in formatting source code as you can see below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Security.Principal;
using System.ServiceModel;

namespace WindowsFormsApplication1
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Happy blogging.

Posted by Posted by pc under Filed under Blog, Technical Comments 1 Comment »

06th Nov 2009

Why we should be testing the release build and not the debug build

If we are deploying the release build of an application, you should be testing the release build of the application. While it doesn’t sound like a big deal, subtle errors arising from the compiler optimizations can bite you in production. Here is an example of it.

As I mentioned in a previous post, one of solutions for the access denied issue was to pre-load the assemblies in the Global.asax Application_Start event handler. For preloading a specific assembly (lets call it foo.dll) I did something like this:

MyNamespace.MyClass.Equals(null, null);

Things worked fine in the debug build, but in the release build we were getting Access denied for the foo.dll assembly. It was a little weird because all the other assemblies were getting loaded as network service and they all succeeded. Foo.dll was getting loaded under the identity of the user and was failing. I decompiled the foo.dll using Reflector (can’t say how many times this nifty little tool saved the day) and found that the code was optimized by the compiler to this:

object.Equals(null, null);

It does make sense. In hindsight.

We tested the solution in debug build where there was no optimization and everything worked as expected.

So my advice is – if you are deploying the release build of an application, you should be testing the release build of the application.

P.S. – There was an interesting discussion in the MSDN forums a couple of years ago which displayed a similar problem. I will blog about it later, for a little while it got me real frightened about my understanding of the .net platform.

Posted by Posted by pc under Filed under .NET, C#, Technical Comments No Comments »

04th Nov 2009

Getting Access Denied Errors in your WCF service or ASP.NET application ?

We are using impersonation in our WCF Service so that credentials of the user can flow to the backend layer (where authorization is done). Strangely we were getting Access Denied errors when the client tries to connect to the service. The error message was like:

Could not load file or assembly ‘MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’ or one of its dependencies. Access is denied.

This was very frustrating to say the least. The first thing to do was search the internet with the error message and sure enough, several other people had faced the same issue but nobody had a good solution for the problem. The problem was that the code was running under the identity of the user (because we were using impersonation) and when the assemblies were shadow copied to the “Temporary ASP.NET Files” directory (C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files), the user did not have write permissions to that directory and hence the Access denied error.

Note: I should say that the Fusion Log Viewer was extremely helpful in identifying the problem and helping to make sure that the problem was resolved.

The obvious solution is to give users write permission to that folder. The testing team decided that this could a potential security issue (even though this was an internal application and permissions were given only to authenticated users). So we began hunting for other solutions and came up with more solutions.

  • Run aspnet_regiis –ga “authenticated users”.

This seemed to fix the problem, but it turned out that it was just a variation of granting authenticated users permission to the Temporary ASP.NET Files folder. What this command does is add the user/user-group to the IIS_USRS groups which is already set to have modify permissions on the Temporary ASP.NET Files folder. It works, but we are back to square one.

  • Disable Shadow copying of assemblies

As I mentioned earlier, the problem was occurring while shadow copying the assemblies to the temp location. The primary purpose of shadow copying is to do dynamic compilation and hot-swapping files. Dynamic compilation does not apply to WCF as much as for ASP.NET. Also we were not very concerned about the hot-swapping of files, so this was a credible option for us. But what concerned us was that we couldn’t find any info about any other side effects of disabling shadow copying. To disable shadow copy, add the following in your web.config inside the configuration section.

<system.web>
    <hostingEnvironment shadowCopyBinAssemblies="false"/>
</system.web>

The good thing about this option is that it does not require a code change and is easy to revert and also there doesn’t appear to be any security issues.

  • Move impersonation to the end of the call stack

Since the problem occurs because the assembly loading happens in the identity of the user, we could do away with declarative impersonation and do an imperative style impersonation where impersonation is done only when making calls to the backend system. To make it more clear, we were doing impersonation like:

[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public Response DoSomething(Request request)
{
        return request.Execute();
}
Instead we could do impersonation only while calling the backend code:
WindowsIdentity callerWindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
    throw new InvalidOperationException("The caller cannot be mapped to a WindowsIdentity");
}

using (callerWindowsIdentity.Impersonate())
{
    // Make backend calls
} 

This is definitely a good solution, but has atleast two drawbacks. The first problem (not a big one) is that it requires a code change. The second problem is a performance one and happens only if the backend calls are webservice calls. The reason for this is that the webservice calls usually require a XmlSerializers dll which is generated by Visual Studio and usually deployed along with the application. If this assembly is not present, the runtime will create one dynamically. This can cause a perf hit. Since we do impersonation before making the backend call, the XmlSerializer assembly is loaded in the identity of the user and will fail. But the CLR, failing to bind the assembly, will synthesize one for you thus causing a perf hit.

If your backend calls are not webservice calls, then this is a reasonable workaround for you.

  • Pre-load the assemblies

What we understood from the Fusion Logs was that the assembly loading was happening under the identity of the end user who does not have adequate permissions. So one thing we can do is to pre-load the assemblies when the service is running as the network service account. To do this, we created a Global.asax file and in the Application_Start event handler, we refer to types in all the assemblies of the service, thus forcing them to be loaded even before the first request is processed. The code looks something like this:

namespace MyService
{
    public class Global : System.Web.HttpApplication
    {

        protected void Application_Start(object sender, EventArgs e)
        {
            //Make sure all the dlls are loaded
            Action action = new Action(null);
            EntityOperations.EntityOperationsFactory.CreateOperation();
            DataAccess.DaoFactory.CreateDao(); 
            WebServiceLibrary.WebServiceGateway.Initialize(null);
        }
     }
}

Using the Fusion Logs we were able to see that the assemblies were getting loaded under the identity of the network service account. We could also see that the XmlSerializers were also getting loaded correctly.

This solution might feel a little icky because of its unconventional nature but I think it is a brilliant solution and it seems to work correctly. We have decided to adopt this solution for our project.

  • Change the shadow copy directory to a directory inside the website directory

Frankly I never tried this one out and don’t know if it works, but it is worth some investigation if none of the solutions outlined above works for you.

I will make a follow up post or edit this one, if I find problems with the solutions mentioned here or if I find better solutions.

Posted by Posted by pc under Filed under .NET, C#, Technical, WCF Comments 2 Comments »

04th Nov 2009

Adding a desktop shortcut using Wix

Creating installers is a pain in the ass.

We had to move from ClickOnce to MSI (for reasons bizarre) and we chose Wix (it was easy considering the fact that there was only one option to chose from).

While Wix doesn’t help much in easing the pain (and in some ways it makes things worse), it sure does help in automating the creation of your MSI. While I would like to see a much simpler, automate-able solution for creating MSIs, if you need to do something today Wix is the way to go. Wix is a little complex and unintuitive to use (maybe because of the nature of the underlying technology – MSI). Whatever the reason, I found that creating shortcuts is not as straight forward as one would expect it to be. I would expect to set some attribute to true (like in ClickOnce) and be done with it, but it was not so. Hence this blog post.

The following steps are for creating desktop shortcuts, it differs for creating shortcuts in the Start->Programs list.

First, you need to add the following line

<Directory Id="DesktopFolder" Name="Desktop"/>

Then add a shortcut node under the File node corresponding to the file for which you want the shortcut.

<File Id="StartupExecutable" Name="$(var.StartupExecutable.TargetFileName)" Source="$(var.StartupExecutable.TargetPath)" DiskId="1" KeyPath="yes">
               <Shortcut Advertise="yes"
                         Id="MyProductDesktopShortcut"
                         Directory="DesktopFolder"
                         Name="Name of desktop shortcut"
                         WorkingDirectory="INSTALLLOCATION"
                         Description="Some description"
                         Icon="Icon.exe">
                 <Icon Id="Icon.exe" SourceFile="$(var.StartupExecutable.TargetPath)" />
               </Shortcut>
             </File>

To give a perspective, the whole thing should look like this:

<Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="DesktopFolder" Name="Desktop"/>
      <Directory Id="ProgramMenuFolder">
        <Directory Id="ApplicationProgramsFolder" Name="My Company Name"/>
      </Directory>
      <Directory Id="ProgramFilesFolder">
        <Directory Id="MyCompanyFolder" Name="My Company Name">
          <Directory Id="INSTALLLOCATION" Name="My Product Name">
            <Component Id="MyComponent" Guid="1c4ba634-0428-4bcd-ad46-c7cf232e007b">
              <!-- Add our project output dll's -->
              <File Id="StartupExecutable" Name="$(var.StartupExecutable.TargetFileName)" Source="$(var.StartupExecutable.TargetPath)" DiskId="1" KeyPath="yes">
                <Shortcut Advertise="yes"
                          Id="MyProductDesktopShortcut"
                          Directory="DesktopFolder"
                          Name="Name of desktop shortcut"
                          WorkingDirectory="INSTALLLOCATION"
                          Description="Some description"
                          Icon="Icon.exe">
                  <Icon Id="Icon.exe" SourceFile="$(var.StartupExecutable.TargetPath)" />
                </Shortcut>
              </File> 
              <!—Rest of your project assemblies –>
              <File Id="MiddleTier" Name="$(var.MiddleTier.TargetFileName)" Source="$(var.MiddleTier.TargetPath)" DiskId="1" />
              <File Id="Backend" Name="$(var.Backend.TargetFileName)" Source="$(var.Backend.TargetPath)" DiskId="1" />
        </Component>
</Directory>

I hope this was helpful for you fellow journeyman.

Posted by Posted by pc under Filed under Technical Comments No Comments »