Monday, February 18, 2013

Implementing POST requests in .NET

Data transfer between the client and server takes place over the sockets and in byte format. Which means that anything a client needs to send to a server must be converted into bytes either implicitly or explicitly.
POST requests differ from other HTTP requests (apart from PUT) in the concept that in POST request, the client sends data in the 'body' of the HTTP packet. Hence we should understand how to send this data on the client side and at the same time how do we extract the body from the HTTP packet on the server side for further processing. Most of the sites only speak about the GET requests which are far simpler to consume by any client. It is the POST/PUT requests which needs to be understood very well.

As mentioned earlier, the data needs to be sent as a stream of bytes hence if you need to transfer an object of a class then it must be serialized into a stream of bytes by serialization. This post relates with JSON (de)serialization.

Lets take a look at some client and server side code in .NET.

Client Side:


string endPoint = "http://localhost:20909/surveyupload"; // endpoint address to send the data on
var request = (HttpWebRequest)WebRequest.Create(endPoint);
request.Method = "POST";          

string PostData = Newtonsoft.Json.JsonConvert.SerializeObject(survey); // JSON serialization

if (!string.IsNullOrEmpty(PostData))
{                  
         byte[] byteContent = Encoding.UTF8.GetBytes(PostData);                

         using (var writeStream = request.GetRequestStream())
         {
                writeStream.Write(byteContent, 0, byteContent.Length);
          }
  }



using (var response = (HttpWebResponse)request.GetResponse())
{
      var responseValue = string.Empty;

      if (response.StatusCode != HttpStatusCode.OK)
      {
              var message = String.Format("Request failed. Received HTTP {0}", response.StatusCode);
                        throw new ApplicationException(message);
       }

       // grab the response
       using (var responseStream = response.GetResponseStream())
       {
             if (responseStream != null)
             using (var reader = new StreamReader(responseStream))
             {
                   responseValue = reader.ReadToEnd();
               }
         }
}


Server side:
The following method is your sample function implemented on the server side, that maps to the endpoint request made from client.


public string GetFile(System.IO.Stream data)
        {
            string JSONInString = string.Empty;
            using (StreamReader reader = new StreamReader(data))
            {
                JSONInString = reader.ReadToEnd();
                reader.Close();            
            }
            // Deserialize the streamed byte data into the object of known type as below
            SurveyData ReceivedData = JsonConvert.DeserializeObject<SurveyData>(JSONInString);
            if (ReceivedData != null)
                return "Success";
            else
                return "Failed";
        }

That's it. It is very easy to implement the POST requests in .NET. The above client requests can be further elaborated depending upon the requirement. This may involve adding additional headers, modifying content-types, user-agent, etc. properties of the Http request.

For details regarding the importance of REST services, please refer to, http://intelligentfactory.blogspot.co.uk/2012/09/rest-services-primer-all-about-rest.html

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.