Thursday, October 11, 2012

[JavaScript] 'window.onbeforeunload' fires twice.

It is a common practice to handle the 'unsaved data on page' scenario by means of handling 'window.onbeforeunload' event. A typical way of handling this event would be like this. 

window.onbeforeunload = handleUnsavedData; 


       function handleUnsavedData()
       {
              if (pageUpdated)
              {
                     return 'You have unsaved data on the page. Are you sure you want to    navigate away from the page?';
              }
       }


This works, but you may have noticed that the 'onbeforeunload' event is getting fired twice, effectively executing the function 'handleUnsavedData' twice! 

Well, there is a work around for this. The solution is to disable the event handler. So the code would look like below. 

function handleUnsavedData() 
{ 
if(pageUpdated) 
{ 
event.returnValue = 'You have unsaved data on the page. Are you sure you wan to navigate away from the page?'; 
window.onbeforeunload = null; 
} 
} 

Now this makes sure that the event is not fired twice - only to introduce a new problem! 
Imagine that you have chosen not to exit the page when you were warned. Now you are back in your page (without a post-back ofcourse). If you try to navigate away from the page again, will it warn you? Of course not, because you have nullified the event handler. 

Luckily there is a work around for that too :-) 

The idea is to temporarily disable the event handler and then enable it later(within few milliseconds). The modified code would look like below. 

function handleUnsavedData() 
{ 
if(pageUpdated) 
{ 
event.returnValue = 'You have unsaved data on the page. Are you sure you wan to navigate away from the page?'; 
window.onbeforeunload = null; 
setTimeout("enableBeforeUnloadHandler()", "100"); 
} 
} 

function enableBeforeUnloadHandler()  {     window.onbeforeunload = confirmExit; } 

In this case, the event handler would be reinstated shortly after returning to the page. You may want to play with the '100 ms' a little bit to suit your requirements. 


Happy coding, 

James Poulose

Friday, April 13, 2012

[C#] Validate a method’s signature in run time

Usage of interfaces is always the recommended way to enforce a method’s signature – there are no doubts in that. But there are some occasions where you cannot use an interface to achieve this.
I had a scenario this week, in which I had to use some methods dynamically by reflecting them in run time. Basically these assemblies are created by others and I just consume the methods in run time.  To add more problem, there can be any number of these methods. Even though there is an agreed signature for these methods, often times people can forget those ‘trivial’ details, resulting in run time exceptions, which may not be a nice thing to happen in a production system J.
So I wrote a little validation method which will validate a specified method against my signature. First define a delegate which matches your requirement.
delegate bool MyDesiredSignature(string param1, string param2);


Now extract the method info from the user’s assembly and attempt to create a delegate which matches my delegate (in this case it will be MyDesiredSignature).
bool ValidateSignature(string methodName, object typeInstance, Type delegateType)
{
      MethodInfo methodInfo = this.GetType().GetMethod(
            methodName, // The method's name.
            BindingFlags.Instance | BindingFlags.NonPublic); // Change this accordingly for static/public methods.

      // Attempt to create a delegate of my delegate type from the method info.
      Delegate methodDelegate = Delegate.CreateDelegate(delegateType, typeInstance, methodInfo, false);

      // If we have 'methodDelegate' as null, then that means the delegate does not match our signature
      // or else we have a match.
      return (methodDelegate != null);
}

Now we can just call this method for method verification like this.

bool isValidSignature = ValidateSignature("UsersMethodName", this, typeof(MyDesiredSignature));


Happy coding!
James Poulose

Monday, April 9, 2012

[C#] WCF:Pass meta data from host to implementation.

I have two WCF hosts (one on TCP and another on NamedPipes). Don’t be alarmed about the multiple hosts – this is a messaging engine and hosts are mounted dynamically based on the configuration. No matter how many types of hosts I have, there is only one service implementation. Now the problem is, when my service implementation is invoked by an incoming call, how do I identify whether it was from host A or host B? 
Well, I need to pass some meta data from the host to my implementation class. How do I do it? There are two ways
  1.  Using an instance of the implementation

 I found a nice solution for the issue I was facing. Normally when we host a WCF endpoint this is the code we follow.

ServiceHost serviceHost = new ServiceHost(typeof(IService))

Here you pass in the type of the interface you expose to the ServiceHost instance. Instead of this approach, you can make use of the second overload of the ServiceHost constructor which takes in an instantiated object! Now the code looks like this

ServiceImplementation implementation1 = new ServiceImplementation();
ServiceHost serviceHost = new ServiceHost(implementation1);

Only thing to note here is that you need to mark your implementation instance mode as a ‘InstanceContextMode.Single‘, effectively making it a Singlreton.

Now the way it solves my problem is that I use my implementation class to pass any metadata from the host to the implementation. My code now looks like this.

// Create a metadata class just to hold your data.
public class MetaData     
{     
       public MetaData(string data1,int data2) 
       {     
              Data1 = data1;      
              Data2 = data2;      
       }
      
       public string Data1 { get; set; }
       public int Data2 { get; set; }   
}

// Just pass in the instance to the host.
MetaData metadata = MetaData("D1", 100);
ServiceImplementation implementation1 = new ServiceImplementation(metadata);
ServiceHost serviceHost = new ServiceHost(implementation1);

       // My Implementation looks like this
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

internal class ServiceImplementation : IService
{     
       private MetaData m_MetaData;     
       public ServiceImplementation(MetaData metaData)
       {     
              m_MetaData = metaData;    
       }     

       public string Ping(string name)  
       {     
              return m_MetaData.Data1;  
       }     
}

See that you have all your meta data in the member ‘m_MetaData’.

2. Using a derivation of ServiceHost

Create a derivation from the 'ServiceHost' class with some additional information



public class ServiceHostWithMetaData : ServiceHost
{     
       private MetaData m_MetaData;  
       public MetaData MetaData
       {
           get { return m_MetaData; }
       }

   
       public ServiceHostWithMetaData(MetaData metaData, Type serviceType, params Uri[])
       {     
              m_MetaData = metaData;    
       }     
}

  Now you can access your metadata in the following way.

            ServiceHostWithMetaData hostWithMetaData = (ServiceHostWithMetaData)OperationContext.Current.Host;
            MetaData metaData = hostWithMetaData.MetaData;

This should get you going.

Monday, May 2, 2011

[C#] Dynamic Web Service Invoker

Invoking a web service dynamically is not a new topic. I have been using the following method to invoke a web service without a proxy till recently. Later below you can see a better way of doing this.

Create your SOAP envelope and contents. You will be playing with some strings for a while.

The conventional method


 // Create and furnish the basic requestor
HttpWebRequest oHttpWebRequest = (HttpWebRequest) WebRequest.Create(URL);
oHttpWebRequest.UseDefaultCredentials = true;
oHttpWebRequest.ContentType = "text/xml";
oHttpWebRequest.Method = "POST";
oHttpWebRequest.Accept = "text/xml";
oHttpWebRequest.Headers.Add("SOAPAction:" + SoapAction);
oHttpWebRequest.UserAgent = "Mozilla/4.0+";
// Encode and post the request
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(sSoapMessage);
Stream oSendStream = oHttpWebRequest.GetRequestStream();
oSendStream.Write(bytes, 0, bytes.Length);
oSendStream.Close();
// Get the response
oHttpResponse = (HttpWebResponse) oHttpWebRequest.GetResponse();
Stream oReceiveStream = oHttpResponse.GetResponseStream();
// Manipulate the stream and extract data here
oHttpResponse.Close();
oReadStream.Close();

I have omitted many plumbing statements here as this is intended only to give a basic idea about how difficult this is. 

A different  approach

The next method also technically works the same way, because there is only one way a SOAP request can be made. Only difference is that the new approach wraps the whole string manipulation inside itself and does all plumbing work for us. The basic idea is to generate a proxy assembly when you need as a one time activity.

Uri uri = new Uri(_mUrl); // Create the uri object
WebRequest webRequest = WebRequest.Create(uri);

// Supply credentials, if required
Authenticate(webRequest);

WebResponse webResponse = webRequest.GetResponse();
Stream requestStream = webResponse.GetResponseStream();
// Get a WSDL file describing a service
ServiceDescription serviceDescription = ServiceDescription.Read(requestStream);
// Initialize a service description importer
ServiceDescriptionImporter descriptionImporter = new ServiceDescriptionImporter();
descriptionImporter.AddServiceDescription(serviceDescription, String.Empty, String.Empty);

//The allowed values of this property are:  "Soap", "Soap12", "HttpPost" ,"HttpGet" and "HttpSoap".
//The default value is "Soap", which indicates the SOAP 1.1 standard. This is case sensitive.
descriptionImporter.ProtocolName = "Soap";
descriptionImporter.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties;
CodeNamespace codeNamespace = new CodeNamespace();

// Compile to assembly
compilerResults = codeProvider.CompileAssemblyFromDom(compilerParameters, codeCompileUnit);
Assembly assembly = compilerResults.CompiledAssembly;

// We have a valid assembly now. Try to get the Type from it.
Type type = assembly.GetType(_mTypeName) ?? FindTypeByName(assembly);

// Create the object instance
_mTargetInstance = assembly.CreateInstance(_mTypeName);
// Get the method info object
_mMethodInfo = type.GetMethod(
_mMethodName,
BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.IgnoreReturn);

// Invoke the method with necessary arguments
object result = _mMethodInfo.Invoke(_mTargetInstance, parameters);

The advantage in this approach is that you need to execute this whole thing only once when you find the MethodInfo object as null (for the first time). The rest of the times this will behave just like a normal web service invoke using the conventional method.

I know you might be thinking that why should you do like this? Why can’t I invoke like the old way? Well the answer is ‘it depends’. There are some situations where you decide to post a piece of data to a web service who’s URL, method and parameters are known only at run-time, probably from a database configuration or a config file. I found this very useful for my application integration project.
Enjoy coding and let me know if you need help in this.

Genesis


I have been a  'Googler' for the past many years. For each and every thing, no matter whether it is a silly doubt or a difficult problem, there was always somebody out there with the same 'problem' and amazingly there was also another person with a solution exactly for that! That's the power of community based development.

I believe that all of us who have benefited from this community service also have inherited the responsibility to give it back when ever you have something worth sharing. As we develop software most of us would have found solutions for many problems and it must be lying somewhere in your hard disk forgotten. Those might be 'simple stuff' to many out there, but will definitely be 'valuable' to at least a few beginners.

So I decided to find a place to 'dump' all my snippets and I narrowed in here. Now I need a name for my blog. Well, I decided to choose Tech Mentis as a name. Wondering what on earth this Mentis is? Don't worry, it's just the Latin name for mind :-). Wasn't that simple?

Enough of bootstrapping, let me make this a bit useful now.

Thanks for reading,
James Poulose