Wednesday, October 31, 2012

Geolocation sample in HTML5

Geolocation is an interesting feature deployed by numerous mobile applications. It allows an application to find the location of mobile/device. And based on the location the application can provide various services or advertisements.

Geolocation in HTML5?
HTML5 allows one to use to geolocation services quite easily and within few minutes one should be able to see something working.

lets see an example of how to use the geo location in HTML5.

One needs to use the geolocation object exposed by the navigator in-order to  utilize its services. The geolocation object has 2 methods which provide the location information.
1) getCurrentPosition : to be used when the location information is required just once.
2) watchPosition : to be used when one needs to monitor or track the location periodically.

Both the methods have identical signatures. The arguments for each of the functions is as below,
a) Arg1 (Mandatory) : call back function, which will be called when the function call suceeds
b) Arg2 (Optional) : call back function, which will be called when the function call fails
c) Arg3 (Optional) : PositionOptions object

The following code will show a button and on clicking the button the virtual globe should be visible. In Firefox one would see the info bar and a message box prompting the user to accept the location information.

Paste the following code in the <body> of an html file.
<p>
<button onclick="GetMap()">Show map</button>
</p>
<div id="mapDiv" style="position: relative; width: 800px; height: 600px;"></div>
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
<script>

            var map = null;
            function GetMap() {
                /* Replace YOUR_BING_MAPS_KEY with your own credentials.
                    Obtain a key by signing up for a developer account at
                    http://www.microsoft.com/maps/developers/ */
                var cred = "<Your BING KEY>";
                // Initialize map
                map = new Microsoft.Maps.Map(document.getElementById("mapDiv"),
                    { credentials: cred });
                // Check if browser supports geolocation
                if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition(locateSuccess, locateFail);
                }
                else {
                    alert('I\'m sorry, but Geolocation is not supported in your current browser.');
                }
            }



           // Successful geolocation
            function locateSuccess(loc) {
               // Set the user's location
               var userLocation = new Microsoft.Maps.Location(loc.coords.latitude, loc.coords.longitude);
             
               // do your operations
            }

            // Unsuccessful geolocation
            function locateFail(geoPositionError) {
                switch (geoPositionError.code) {
                    case 0: // UNKNOWN_ERROR
                        alert('An unknown error occurred, sorry');
                        break;
                    case 1: // PERMISSION_DENIED
                        alert('Permission to use Geolocation was denied');
                        break;
                    case 2: // POSITION_UNAVAILABLE
                        alert('Couldn\'t find you...');
                        break;
                    case 3: // TIMEOUT
                        alert('The Geolocation request took too long and timed out');
                        break;
                    default:
                }
            }

</script>

That's it. Plain and simple to get location information in HTML5.

Sunday, September 9, 2012

REST Services : A Primer. All About Rest Services

Today we will understand how to consume the WCF REST services on the client side.
The theory of REST can be understood from numerous resources online. This post will explain how to make the different types of requests.

Why REST?
Anyone who has worked with web-services and WCF is often confused as to why one should create RESTful services when SOAP has been easy and good to use for so long. So the short answer for using REST is less data traffic on the network. Every data packet to be sent over SOAP is packaged in a bulky header.

The main verbs in a REST implementation are GET, PUT, POST. There are other verbs as well but they are infrequently used. One can try these requests by using a popular tool like WebFetch (we will discuss using the WebFetch tool in a later post)

Lets go to some practical examples:
In many applications viz the secured ones, every client is issued a certificate so that every REST request from the client is authenticated and then authorised to perform the operation (specified by the verb)

How to use the client certificates in REST:
HttpClient client = new HttpClient( <Url on which request is to be made> );

string certLoc = <certificate location>;
string certPwd = <certificate pwd>;

X509Certificate2 cert = new X509Certificate2(certLoc, certPwd);
client.TransportSettings.ClientCertificates.Add(cert);


1) The complete sample for GET request would look as below,

using (HttpClient client = new HttpClient( <Url on which request is to be made> ))
            {
                // Initalise a response object
                HttpResponseMessage response = null;

                string certLoc = <certificate location>;
                string certPwd = <certificate pwd>;

                X509Certificate2 cert = new X509Certificate2(certLoc, certPwd);
                client.TransportSettings.ClientCertificates.Add(cert);

                string sRestAddress =  <Url on which request is to be made>;
                client.BaseAddress = new Uri(sRestAddress);

                // encoding to be used. base64_UTF16_Encode is a user-defined function
                string sBase64EncodedMembershipNumber = base64_UTF16_Encode(sMembershipNumber);

                string authrorization = "Basic" + sBase64EncodedMembershipNumber + "\r\n";
                client.DefaultHeaders.Authorization = new Microsoft.Http.Headers.Credential(authrorization);             
                client.DefaultHeaders.Accept.Add("text/xml\r\n");             

                string requestPath = <request path of the resource>;

                // Make the request and retrieve the response
                response = client.Get(sRestAddress + requestPath);
                response.Content.LoadIntoBuffer();              
                return response.Content.ReadAsByteArray();
            }


The above code snippet shows how we can make a GET request and pass the client certificate and logging credentials along with the request. Response could either be in xml or pdf format and can be specified in the header by using the Accept type in the HTTP request.

2) The PUT request would look like below,

using (HttpClient client = new HttpClient( <Url on which request is to be made> ))
            {
                // Initalise a response object
                HttpResponseMessage response = null;

                string certLoc = <certificate location>;
                string certPwd = <certificate pwd>;

                X509Certificate2 cert = new X509Certificate2(certLoc, certPwd);
                client.TransportSettings.ClientCertificates.Add(cert);

                string sRestAddress =  <Url on which request is to be made>;
                client.BaseAddress = new Uri(sRestAddress);

                // encoding to be used. base64_UTF16_Encode is a user-defined function
                string sBase64EncodedMembershipNumber = base64_UTF16_Encode(sMembershipNumber);

                string authrorization = "Basic" + sBase64EncodedMembershipNumber + "\r\n";
                client.DefaultHeaders.Authorization = new Microsoft.Http.Headers.Credential(authrorization);           
                client.DefaultHeaders.Accept.Add("text/xml\r\n");             

                string requestPath = <request path of the resource>;
             
                // XML file which contains the data to be sent
                XDocument doc = XDocument.Load(@"C:\Personal\Test.xml");

                HttpContent body = HttpContent.Create(doc.ToString(SaveOptions.DisableFormatting), Encoding.UTF8, "text/xml");

                response = client.Put(sRestAddress + requestPath, body);
                response.Content.LoadIntoBuffer();              
                return response.Content.ReadAsByteArray();
            }

The above code snippet shows how to send a PUT request to the server. PUT/POST requests are used to send data to the server. The exact type of verb to be used is decided by the author of the Server code and the requirement whether the state of server is to be changed or not.

REST is fairly easy and simple to use.

Thursday, August 2, 2012

Excel Named ranges in EPPlus

This post will explain the advantages of Named Ranges in Excel and how do we use it with EPPlus library.
This post would explain how to use the named ranges for reading/importing an excel programmatically(dynamically).

A) What are Named Ranges?
In excel, it is possible to specify an address for a cell or a range of cells. The address of this/these cells is referred as named ranges.


If you check the above image, cell A1 has a text value of "Name" and named range of it is"NameField".
Named Range in other words are user-defined addresses of cells.
Now, since named ranges are addresses, basic rules of variable names apply. Like, it cannot begin with a number, cannot have a '.' character in the name, etc. Also, within a sheet, all the named ranges must have unique names.

B) Writing named ranges using EPPlus:
Many engineering applications (software) provide feature of exporting and importing the excel file. The typical scenario will be to generate some kind of a template information in the form of an excel, exporting to the client from server.
The exported excel file can then be populated from the users and once that is done, the excel file can then be imported into the system by sending it to the server over a web.

In such scenarios, importing an excel will be extremely easy only if we were to write the user defined addresses of the cells along with its text, while exporting. So that while reading we can read only our user-defined addresses.

Assumption:
Users are aware of How to use EPPlus library and the popular APIs it exposes.

ExcelRange range = ws.Cells["A1"];           // ws is the worksheet name
ws.Cells["A1"].Value = "Name";
string sNamedRange = "NameField";
ws.Names.Add(sNamedRange, range);

That's it. A1 cell in your generated excel file must have "NameField" as its address.

Hope this post helps a lot of other developers. I had a tough time reading the excel file.



How to change the orientation of excel worksheet in EPPlus

It is very easy to change the orientation of the Excel sheet while using EPPlus library. This is often necessary when one needs to check the print preview of the generated excel file.

Suppose, your worksheet variable name is ws then,
ws.PrinterSettings.Orientation = eOrientation.Landscape.

Thats it. It is a simple one-liner.

Friday, July 27, 2012

NPOI or EPPlus? Which is better?

In my current project, I had a requirement to export and import the data to an excel file. There are plenty of free libraries available, but only NPOI and EPPlus are worth taking a look.

After initial searching and experimentation, i have come to the following conclusion.
Pls. note that these conclusions have been arrived at, only after my personal trials.

NPOI
1) The library is good and extensive, but the API's are not at all intuitive and user friendly
2) Performance in terms of time and memory, is a big disappointment.
3) The only advantage in favour of NPOI, according to me, is its ability to generate xls and xlsx files.

EPPlus
1) The library is very well written and API's are user-friendly, very much identical to Interop.excel
2) Performance is big big gain while using EPPlus. Thousands of cells can be read/written in a matter of seconds.
3) It can generate file only in xlsx format. No facility of xls. But one can always download the Microsoft Compatibility pack to overcome this problem.

Wednesday, July 18, 2012

WCF Service Traces using SVC Trace Viewer

In WCF projects, one would invariably need some kind of mechanism to ascertain whether the data is sent/received over the communication channel. One can definitely use fiddler for monitoring the data traffic over an http channel. But, WCF tracing provides a nifty way of verifying whether the data has been received/sent from WCF side.

It is easy to add the Tracing information in the WCF project. One would just need to add the diagnostics element in the web.config / app.config file of the WCF hosting project.
A sample element structure is shown below.

<system.diagnostics>
    <sources>
      <source name="System.ServiceModel" switchValue="Information" propagateActivity="true">
        <listeners>
          <add name="corr"/>
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging">
        <listeners>
          <add name="corr"/>
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="corr" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\personal\Service.svclog">
      </add>
    </sharedListeners>
  </system.diagnostics>

"c:\personal\Service.svclog" is the absolute file path for the log file that will be generated from the WCF traces.
Navigate to the file location and view the log file in the SVC Trace Viewer for easy debugging.

Friday, July 6, 2012

Logging using log4net

In almost every application (windows or web based) one needs to monitor the health of the system. Meaning, every application invariably maintains an audit trail which can be inspected by the development team in-order to understand the application flow and rectify the errors (if any).

I have been addressing the above requirement by implementing a singleton, thread-safe logger class for such purposes.

But recently, I learnt a much easier way to do the logging using a freely available library named as log4net.

log4net dll can be downloaded from Log4net.

1) Inorder to use log4net we need to configure the expected behavior in the app.config or web.config files (depending upon the application type)
I am explaining only the web.config part here. But the same holds good for app.config.

1.1) Create a new section node under the <configSections>  in the web.config file as shown below
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>

1.2) Now, create a log4net node in the web.config file,

<log4net>
<!-- Console Appender -->
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.SimpleLayout"/>
</appender>

<!-- File Appender -->
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value=""/>
               <StaticLogFileName value="false"/>
               <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
              <appendToFile value="true"/>
<rollingStyle value="Composite"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="10MB"/>
             <datePattern value=".yyyy-MM-dd'.lo\g'"/>
<encoding value="unicodeFFFE"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
</layout>
</appender>
<root>
<level value="ALL"/>
<appender-ref ref="RollingLogFileAppender"/>
</root>
</log4net>

The best part of log4net is that you can have multiple appenders for logging the data. Also, several processes can log to the same file, provided you do the correct settings in the <lockingModel> node.

So, as per the above settings,
we are asking log4net library to create a Rolling log file, with lockingModel type as MinimalLock [for multiple processes to log to same file], each file size to be of 10MB and maximum file backups to be maintained as 10.
Further, the file name should end with ".yyyy-MM-dd.log". where yyyy-MM-dd represents the file creation date.

Usage:


log4net.Appender.IAppender[] AppenderList = D2DELLogger.ms_log.Logger.Repository.GetAppenders();
                        foreach (var item in AppenderList)
                        {
                            if (item.Name == "RollingLogFileAppender")
                            {
                                ((log4net.Appender.RollingFileAppender)(item)).File = Path.Combine(System.Configuration.ConfigurationManager.AppSettings["LogFilePath"].ToString(), "D2DLogs\\D2DTrace.log");
                                ((log4net.Appender.RollingFileAppender)(item)).ActivateOptions();
                            }
                        }

Note: We are calling ActivateOptions() method, because the configuration properties are being modified in the preceding line. [ in a real world scenario, every application would be developed to have a customizable file name, hence we modify the file name that was configured via. the web.config file].

Hope this post helps everyone.






Tuesday, July 3, 2012

Method extensions and Useful Enum Method Extension

In many of the projects, there is a requirement to get the string values from the enum definition.
One attribute that can be used off-the-shelf is [Flags] attribute. But this attribute gives only the string representation of the enum variable, which means you cannot have spaces or long strings.

So to overcome this, one can write a handy enum extension for this.
Consider the following enum,

internal enum XlColumnHeaders
    {       
        [StringValue("Section")]
        xlSection = 1,

        [StringValue("Question Text")]
        xlQuestionText = 2,

        [StringValue("Free Text")]
        xlFreeText = 3,

        [StringValue("Yes No")]
        xlYesNo = 4,               
    }
Now whenever I wish to get a string representation of xlSection, I should get "Section". Similarly, for xlQuestionText I should get "Question Text" [Note: the space between the 2 words].

To achieve the above result, Create a static class with a public static method as follows.
static class StringEnum
    {
        public static string GetStringValue(this Enum value)
        {
            // Get the type
            Type type = value.GetType();

            // Get fieldinfo for this type
            FieldInfo fieldInfo = type.GetField(value.ToString());

            // Get the stringvalue attributes
            StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(
                typeof(StringValueAttribute), false) as StringValueAttribute[];

            // Return the first if there was a match.
            return attribs.Length > 0 ? attribs[0].StringValue : null;
        }
    }

Usage:
XlColumnHeaders temp = new XlColumnHeaders();
temp = XlColumnHeaders.xlQuestionText;
temp.GetStringValue();             // this would return "Question Text"

Hope this post is helpful.

Saturday, June 30, 2012

Creating drop down options in a cell in Excel using Silverlight 5 and C#

How to create an Out of Browser Silverlight Application for generating Excel? How to create a drop down (combo-box) cell programmatically in Silverlight?

In my current project, I wanted to create a template form in excel that the user can create on his local disk. And later on populate the data according to his wish.

Depending upon the questions in the template, the cells should be customized. E.g. If the question's answer could have 2 choices, say Yes/No then the cell corresponding to such a question must show a drop down for answer choices Yes/No, all done programmatically, behind the scenes.

Assumptions:
1) Silverlight 5 is used
2) Visual Studio 2010 is the development environment.
3) A Silverlight 5 project is created and the reference to Microsoft.CSharp is already added.

A) How to create a out-of-browser Silverlight application?
What is an out-of-browser application: An out-of-browser application (web application) is one which allows  users of that application to access the local hard disk. The exact definition could be easily found on several sites.

Configuring Out-of-Browser settings in VS2010:
For the already created Silverlight project, open the project properties by right clicking the mouse. Select the Silverlight tab on the left.
In Silverlight build options: Select the appropriate Silverlight Target Version, in our case Silverlight 5
Then, tick the "Enable running application out of browser" check box. This would enable the "out-of-browser Settings" button. click on that.
In the Out-of-browser settings new window tick the "Require elevated trust when running outside the browser.
Click OK. 


B) How to create a drop down in the cell
In silverlight we have to use the AutomationFactory for creating an Excel Application object. Here is the code for it.


           dynamic ExcelApp;
            try
            {
                ExcelApp = AutomationFactory.GetObject("Excel.Application");
            }
            catch
            {
                ExcelApp = AutomationFactory.CreateObject("Excel.Application");
            }

            // control visibility of the excel tool
            ExcelApp.Visible = true;

            dynamic m_Workbook = ExcelApp.workbooks;
            m_Workbook.Add();
            dynamic m_WorkSheet = ExcelApp.ActiveSheet;
           
            dynamic cell = null;


Now the tricky part is to do the drop down. And here is the code snippet for creating a drop down in cell [2,2] with options Yes and No.


           dynamic list = new List<string>();
            list.Add("Yes");
            list.Add("No");
                        
            dynamic flatList = string.Join(",", list.ToArray());
            cell = m_WorkSheet.Cells[2, 2];
            cell.Validation.Delete();

            cell.Validation.Add( 3, //XlDVType.xlValidateList,    
                                           3, //XlDVAlertStyle.xlValidAlertInformation,    
                                           1, //XlFormatConditionOperator.xlBetween,    
                                           flatList,
                                           Type.Missing);

            cell.Validation.IgnoreBlank = true;
            cell.Validation.InCellDropdown = true;


You will find many links that use the  Microsoft.Office.Interop.Excel class library for excel Data validation but sadly I did not find a way to reference this library in Silverlight 5. 
Hence, I had to hard-code the XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertInformation, and XlFormatConditionOperator.xlBetween enums in the cell.Validation.Add( ) function above to get all working.


So hope this solves a lot of head ache for others.