Wednesday, 29 September 2010

Javascript: Namespaces and O-O examples...


I'm not sure how common practise this is, but where I currently work we have a standard whereby we placed common JavaScript functionality in separate files and what could be called classes. I'm sure most developers out there do group common functions in files and import them when needed. This is fine, but it doesn't promote certain O-O practises like information hiding and the feel of objects, methods and properties. This is what this post aims to achieve.

I have attached a sample project file which declares a JavaScript name space in a separate file, declares a Messages 'class' in another and a sample HTML page which invokes various methods and properties against it. Sample can be found at the end of this post.


Namespace declaration - Must be imported first
/******************************
** BANTY Namespace definition
******************************/
var BANTY = BANTY || {};
BANTY = (function() {
    return {
        helloWorld : function() {
            return "Helllo World!";
        }
    }
}());



Class definition
/******************************
** Define Messages class
*******************************/
if (!BANTY.Messages) BANTY.Messages = {};
BANTY.Messages = (function() {
 
    // private declarations here
    var pi_Message;
 
    var pi_ChangeMessage = function (newMsg) {
        pi_Message = newMsg;
    };
    
    
    // public declarations here
    return {
        publicProperty : "This is a public property",
        
        init : function (Args) {
            pi_Message = "Message initialised.";
        },
        
        showMessage : function () {
            return "The value of the message is: " + pi_Message;
        },
        
        changeMessage : function (msg) {
            pi_ChangeMessage(msg);
        },
    };
}());



Example HTML Page
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Javascript O-O Example</title>
    <script src="Banty.js" type="text/javascript"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script>
</head>
<body style="font-family: verdana; font-size: 8pt">
    <div id="tagged"></div>
 
    <script src="BANTY.Messages.js" type="text/javascript"></script>
    <script type="text/javascript">
    $('#tagged').append('<br /><div><font color="0000FF"><b>Information hiding principles...</b></font></div>');
    $('#tagged').append('<div>Can I see BANTY?:<b> '+ (BANTY ? 'Yes' : 'No') +'</b></div>');
    $('#tagged').append('<div>Can I see BANTY.helloWorld?:<b> '+ (BANTY ? 'Yes' : 'No') +'</b></div>');
    $('#tagged').append('<div>Can I see BANTY.Messages?:<b> '+ (BANTY.Messages ? 'Yes' : 'No') +'</b></div>');
    $('#tagged').append('<div>Can I see BANTY.Messages.publicProperty?:<b> '+ (BANTY.Messages.publicProperty ? 'Yes' : 'No') +'</b></div>');
    $('#tagged').append('<div>Can I see BANTY.Messages.showMessage?:<b> '+ (BANTY.Messages.showMessage ? 'Yes' : 'No') +'</b></div>');
    $('#tagged').append('<div>Can I see BANTY.Messages.pi_Message?:<b> '+ (BANTY.Messages.pi_Message ? 'Yes' : 'No') +'</b></div>');
    $('#tagged').append('<div>Can I see BANTY.Messages.pi_ChangeMessage?:<b> '+ (BANTY.Messages.pi_ChangeMessage ? 'Yes' : 'No') +'</b></div>');
 
 
    $('#tagged').append('<br /><div><font color="0000FF"><b>Show and Change Messages...</b></font></div>');
    $('#tagged').append('<div><b> BANTY.helloWorld:</b> '+ BANTY.helloWorld() +'</div>');
    $('#tagged').append('<div><b> BANTY.Messages.report():</b> '+ BANTY.Messages.showMessage() +'</div>');
    $('#tagged').append('<div><b> BANTY.Messages.init():</b> '+ BANTY.Messages.init() +'</div>');
    $('#tagged').append('<div><b> BANTY.Messages.report():</b> '+ BANTY.Messages.showMessage() +'</div>');
    $('#tagged').append('<div><b> BANTY.Messages.changeMessage(newmsg):</b> '+ BANTY.Messages.changeMessage("newmsg") +'</div>');
    $('#tagged').append('<div><b> BANTY.Messages.report():</b> '+ BANTY.Messages.showMessage() +'</div>');
    </script>
</body>
</html>



Example Output

Information hiding principles...
Can I see BANTY?: Yes
Can I see BANTY.helloWorld?: Yes
Can I see BANTY.Messages?: Yes
Can I see BANTY.Messages.publicProperty?: Yes
Can I see BANTY.Messages.showMessage?: Yes
Can I see BANTY.Messages.pi_Message?: No
Can I see BANTY.Messages.pi_ChangeMessage?: No

Show and Change Messages...
BANTY.helloWorld: Helllo World!
BANTY.Messages.report(): The value of the message is: undefined
BANTY.Messages.init(): undefined
BANTY.Messages.report(): The value of the message is: Message initialised.
BANTY.Messages.changeMessage(newmsg): undefined
BANTY.Messages.report(): The value of the message is: newmsg




Download Sample Files Here

Thanks go out to my company for putting this standard in place.

ASP.NET - Get IPv4 Address, even if the user is using a proxy or an intranet user


Today I was working on some PayPal integration for an internal web application when part of the API suggested I needed an IP Address for the user to enhance security.

Realising this was an intranet application which could be used externally, I had to cater for all aspects. Getting an IP Address for an internal users involves looking up the host addresses using the System.Net.Dns namespace, rather than a simple peek in a server variable. As well as this, I needed to make sure I could identify real IP Addresses for users behind a proxy. If that wasn;t enough, the PayPal API doesn't support IPv6, so I had to search the host list for a IPv4 address and use that.... PayPal requires an IP or it will fail, so if everything else fails, it will return the loopback address (ack!). here's what I came up with...

UPDATE - Feb 2013
I have provided a couple of updates to this code in light of the comments. Thanks for the input!

Code Snippet
  1.  
  2. // Invoker
  3. string IPAddress = IPHelper.GetIPAddress(Request.ServerVariables["HTTP_VIA"],
  4.                                                 Request.ServerVariables["HTTP_X_FORWARDED_FOR"],
  5.                                                 Request.ServerVariables["REMOTE_ADDR"]);
  6.  
  7.  
  8.  
  9. public class IPHelper
  10. {
  11.     /// <summary>
  12.     /// Gets the user's IP Address
  13.     /// </summary>
  14.     /// <param name="httpVia">HTTP_VIA Server variable</param>
  15.     /// <param name="httpXForwardedFor">HTTP_X_FORWARDED Server variable</param>
  16.     /// <param name="RemoteAddr">REMOTE_ADDR Server variable</param>
  17.     /// <returns>user's IP Address</returns>
  18.     public static string GetIPAddress(string HttpVia, string HttpXForwardedFor, string RemoteAddr)
  19.     {
  20.         // Use a default address if all else fails.
  21.         string result = "127.0.0.1";
  22.  
  23.         // Web user - if using proxy
  24.         string tempIP = string.Empty;
  25.         if (HttpVia != null)
  26.             tempIP = HttpXForwardedFor;
  27.         else // Web user - not using proxy or can't get the Client IP
  28.             tempIP = RemoteAddr;
  29.  
  30.         // If we can't get a V4 IP from the above, try host address list for internal users.
  31.         if (!IsIPV4(tempIP) || tempIP == "127.0.0.1 ")
  32.         {
  33.             try
  34.             {
  35.                 string hostName = System.Net.Dns.GetHostName();
  36.                 foreach (System.Net.IPAddress ip in System.Net.Dns.GetHostAddresses(hostName))
  37.                 {
  38.                     if (IsIPV4(ip))
  39.                     {
  40.                         result = ip.ToString();
  41.                         break;
  42.                     }
  43.                 }
  44.             }
  45.             catch { }
  46.         }
  47.         else
  48.         {
  49.             result = tempIP;
  50.         }
  51.  
  52.         return result;
  53.     }
  54.  
  55.     /// <summary>
  56.     /// Determines weather an IP Address is V4
  57.     /// </summary>
  58.     /// <param name="input">input string</param>
  59.     /// <returns>Is IPV4 True or False</returns>
  60.     private static bool IsIPV4(string input)
  61.     {
  62.         bool result = false;
  63.         System.Net.IPAddress address = null;
  64.  
  65.         if (System.Net.IPAddress.TryParse(input, out address))
  66.             result = IsIPV4(address);
  67.  
  68.         return result;
  69.     }
  70.  
  71.     /// <summary>
  72.     /// Determines weather an IP Address is V4
  73.     /// </summary>
  74.     /// <param name="address">input IP address</param>
  75.     /// <returns>Is IPV4 True or False</returns>
  76.     private static bool IsIPV4(System.Net.IPAddress address)
  77.     {
  78.         bool result = false;
  79.  
  80.         switch (address.AddressFamily)
  81.         {
  82.             case System.Net.Sockets.AddressFamily.InterNetwork:   // we have IPv4
  83.                 result = true;
  84.                 break;
  85.             case System.Net.Sockets.AddressFamily.InterNetworkV6: // we have IPv6
  86.                 break;
  87.             default:
  88.                 break;
  89.         }
  90.  
  91.         return result;
  92.     }
  93. }
End of Code Snippet

Thursday, 23 September 2010

asp:Menu controls not working in Chrome/Safari


I faced a small issue today with asp:Menu controls not working properly in Chrome or Safari the first time the page is loaded. However, if I refresh the page, the contents seem to load fine.
The underlying problem is the way Chrome manages it's adaptors and we need to be able to clear these out and refresh the page if this situation occurs.

I have therefore written an OnInit event for any ASP.NET page or user control in which the menu is placed. Simply just add it in the code behind...


Fix Menu rendering in Chrome and Safari
protected override void OnInit(EventArgs e)
{
    // For Chrome and Safari
    if (Request.UserAgent.IndexOf("AppleWebKit") > 0)
    {
        if (Request.Browser.Adapters.Count > 0)
        {
            Request.Browser.Adapters.Clear();
            Response.Redirect(Page.Request.Url.AbsoluteUri);
        }
    }
}



- Using the "AppleWebKit" we can identify these browsers
- By checking more than one adapter exists, we avoid re-directing every time; this only needs to be done on the first hit.
- We Re-Direct back to itself the first time the page is hit.

Wednesday, 22 September 2010

C#: Cultures


Cultures are things you probably won't come across for general projects unless you are dealing with support for multiple viewing countries. This mainly includes: Dates, times and currencies.

For example, When parsing (using Parse/TryParse) a DateTime object, it assumes the DateTime is in US format... so when we come to use this, we'll notice our days and months are the wrong way round!


Parsing a string in a DateTime object with a UK Culture
using System.Globalization;   // For access to culture objects
 
 
private DateTime ParseDate(string IncomingDate)
{
    CultureInfo ukCulture = new CultureInfo("en-GB");
    DateTime parsedDate = new DateTime();
 
    DateTime.TryParse(IncomingDate, ukCulture.DateTimeFormat, DateTimeStyles.None, out parsedDate);
 
    return parsedDate;
}



An implicit example
DateTime dateObj = DateTime.Parse(inputString, new CultureInfo("en-GB"));



We can also apply culture globally across a whole application by setting culture settings in the Web.config file. In the following snippet, we have Culture and UICulture. The former refers to how DateTime objects and currencies are parsed etc. Using a en-GB culture will ensure these all use UK currencies and formatting. The latter determines which resource files are used for the UI.


Setting the culture globally in the Web.config
<globalization uiCulture="en-GB" culture="en-GB" />

Monday, 20 September 2010

Sending HTML Emails and Emailing Tricks with C#


Sending emails is relatively easy with C#, even-so, its not much more difficult to send HTML based emails either. The formatting, and how different email clients interpret the HTML and CSS in the emails, differs slightly. The aims of this post is to present a few typical scenarios of different types of emails which are sent.

Sending a Simple email using an email server - non-HTML
using System.Net.Mail;
 
 
MailMessage mail = new MailMessage("from@email.com", "to@email.com", "Email Subject", "Email Message");
mail.IsBodyHtml = false;
this.SendMail(mail);
 
 
/// <summary>
/// Sends the mail using a mail message.
/// </summary>
/// <param name="Mail">The mail message.</param>
private void SendMail(MailMessage Mail)
{
     SmtpClient smtpClient = new SmtpClient();
     smtpClient.Host = "Email Server Address";
     smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
 
     try
     {
          smtpClient.Send(Mail);
     }
     catch (Exception ex)
     {
          throw new EmailException(ErrorCodeType.SendFailed, ex);
     }
}


This is enough to send a simple email to a target destination using an existing email server. To enable HTML is the body, we simply enable the IsBodyHtml property of the MailMessage object by setting it to true.


Simple HTML Email using the function in the previous example

MailMessage mail = new MailMessage("from@email.com", "to@email.com", "Email Subject", "<b>HELLO!!</b><br><br>Test Message...");

mail.IsBodyHtml = true;

this.SendMail(mail);



With OutLook for example, some representations of styling alter slightly. For example, I spent some time trying to understand why the line-height was interpreted differently in outlook. For whatever reason, If I tested the HTML template in IE, FF or Chrome; everything would be the same apart from the line-height. This seems to be a common problem. The solution I came up with is to tell outlook to render it in a certain way and that other browsers should ignore it.

HTML Email with line spacing and styles applied to the body of the email
string emailBody = "<div style=\"font-family: Verdana, Arial, sans-serif; font-size: 9pt; mso-line-height-rule:exactly; line-height: 20px\">";
emailBody += "<b>HELLO!!</b><br><br>Test Message...</div>";
 
MailMessage mail = new MailMessage("from@email.com", "to@email.com", "Email Subject", emailBody);
 
mail.IsBodyHtml = true;
 
this.SendMail(mail);


By setting "mso-line-height-rule:exactly" before the line-height property, we are tell mso (Microsoft Office) to render this differently to other browsers. You'll notice that I set the line-height to 20px... for a 9pt font, this is quite huge normally, but in Outlook; it's not.


One more tip, which may be quite trivial to some... If you want to using alias' in your emails (I.e. Appear that the email is being sent from an Alias) then there is no special code. Simply format the 'From' address in the following Format... "AliasName" (Include the quotes aswell)

In a config file, this might look like... [Remember we need to escape special characters in the XML config file!]
<appSettings>
    <add key="Email.FromAddress" value="&quot;WebAdmin&quot; &lt;online@tmgcrb.co.uk&gt;"/>
</appSettings>

Thursday, 16 September 2010

Forcibly clear a printer queue


Sometimes the printer queue just won't clear, no matter how many times you right click and try to delete the job. Here's how to actually clear it out properly!

1. Start > Run > Services.msc

2. Find "Printer Spooler" and stop the service

3. Go to "C:\Windows\System32\spool\PRINTERS" and you will see a list of files. These represent the jobs in the printer queue. Remove these.

4. Restart the "Printer Spooler" service and your queue should be cleared.

Monday, 13 September 2010

View Gradients/Colours properly in your Virtual Machine (VM)


• In the Windows XP operating system (remote system), click on Start menu, then Run.
• Type GPEdit.msc to open Group Policy Editor.
• Navigate to Local Computer Policy -> Computer Configuration -> Administrative Templates -> Windows Components -> Terminal Services.
• In the right pane, double-click on the Limit Maximum Color Depth setting.
• In the Properties dialog, select radio button of Enabled, and then set Color Depth value to 24 bit or Client Compatible

Friday, 10 September 2010

Code Snippit - Determining whether brackets are balanced


We usually have coding challenges at work quite often. This one was quite useful. The aims were to do something that regular expressions struggle doing; that is, determine whether brackets are balanced.

Example of a legal expression: “([as](<{}>))”.
Example of an illegal expression: “({<)>}”.

Here's what I came up with...



private bool IsValid(string str)
{
if (!string.IsNullOrEmpty(str))
{
List<char> LeftParenthesis = new List<char>() { '(', '{', '[', '<' };
List<char> RightParenthesis = new List<char>() { ')', '}', ']', '>' };
List<char> items = new List<char>(str.Length);

// Loop through each character
for (int i = 0; i < str.Length; i++)
{
char c = str[i];

if (LeftParenthesis.Contains(c))
{
items.Add(c); // Add each opening bracket
}
else if (RightParenthesis.Contains(c))
{
int rpIndex = RightParenthesis.IndexOf(c);

// Invalid if there are no open brackets and we find a closing one
int lastPairIndex = items.LastIndexOf(LeftParenthesis[rpIndex]);

if (lastPairIndex >= 0)
{
if (items[items.Count - 1] != items[lastPairIndex]) // Last item must be matching bracket
return false;
else
items.RemoveAt(lastPairIndex); // Remove last pair
}
else
return false;
}
}

// Look for any other brackets left over
if (items.Count > 0)
return false;
}

return true;
}