Posts

....
Technical Blog for .NET Developers ©

Thursday, April 28, 2016

Dynamic Types: Indexers

When we are using Indexers in order to access our variables, we can expand the property through a dynamic reference of the accessed variable, we achieve this through ExpandoObject of System.Dynamic namespace

In this example we set values in a Dictionary type variable, and expand the property name on a dynamic variable


            dynamic Values = new ExpandoObject();

            var _Values = Values as IDictionary<string, object>;

            _Values["Name"] = "Little Writer";
            _Values["Weight"] = 1550.0M;

            string name = Values.Name;
            decimal weight = Values.Weight;


Thursday, February 4, 2016

HTML5 API Indexed Database

API Indexed Database is the officially supported by W3C way for the creation of databases with HTML5

This system takes the concept of key/value pairs to store data. the Database can contain Stores, the equivalent to the SQL tables, and each Object Store contains key/value pairs; this API is not a relational database, but object oriented. you can query this database inline as offline

The first step in this example will be creating a new database, for this we use the open() method, the syntax is as follows:
 
    indexedDB.open("database_name", version)    
    
    
If the database does not exist, it is created, else, it is open. The call to the open() function returns an IDBOpenDBRequest object with a result (success) or error value that you handle as an event

In this example we build the next web form, and implement a Web Method in the server side which returns an array of json objects for loading the database



The js code to open the database and create the object store is the next


    var HTML5DB = {};
    HTML5DB.indexedDB = {};
    HTML5DB.indexedDB.db = null;

    window.indexedDB = window.indexedDB || window.mozIndexedDB || 
                       window.webkitIndexedDB || window.msIndexedDB;
    window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || 
                            window.msIDBTransaction;
    window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || 
                         window.msIDBKeyRange;

    HTML5DB.indexedDB.onerror = function (e) { console.log(e); };

    HTML5DB.indexedDB.open = function () {

        var version = 1;
        var request = window.indexedDB.open("db_example", version);

        request.onupgradeneeded = function (e) {

            var db = e.target.result;
            e.target.transaction.onerror = HTML5DB.indexedDB.onerror;
            var store = db.createObjectStore("object_store", 
                { keyPath: "id", autoIncrement: true });
        };

        request.onsuccess = function (e) {
            HTML5DB.indexedDB.db = e.target.result;
            HTML5DB.indexedDB.getAllRecords();
        };

        request.onerror = HTML5DB.indexedDB.onerror;
    };
        


The code to add and delete records is the next:

Since the id has been declared autoIncrement, we are inserting a record initializing two fields in the value property (value, and timeStamp)


    HTML5DB.indexedDB.addRecord = function (value) {

        var db = HTML5DB.indexedDB.db;
        var trans = db.transaction(["object_store"], "readwrite");
        var store = trans.objectStore("object_store");

        var data = {
            "value": value,
            "timeStamp": new Date($.now()).toLocaleTimeString()
        };

        var request = store.put(data);

        request.onsuccess = function (e) {
            HTML5DB.indexedDB.getAllRecords();
        };

        request.onerror = function (e) {
            console.log("Error Adding: ", e);
        };
    };

    HTML5DB.indexedDB.deleteRecord = function(id) {
      var db = HTML5DB.indexedDB.db;
      var trans = db.transaction(["object_store"], "readwrite");
      var store = trans.objectStore("object_store");

      var request = store.delete(id);

      request.onsuccess = function(e) {
        HTML5DB.indexedDB.getAllRecords();
      };

      request.onerror = function(e) {
        console.log("Error deleting: ", e);
      };
    };
        


The next is the code to retrieve and render records from the database:


    HTML5DB.indexedDB.getAllRecords = function() {

      $('#dbRecords tr').remove();

      var db = HTML5DB.indexedDB.db;
      var trans = db.transaction(["object_store"], "readwrite");
      var store = trans.objectStore("object_store");

      var keyRange = IDBKeyRange.lowerBound(0);
      var cursorRequest = store.openCursor(keyRange);

      cursorRequest.onsuccess = function(e) {
        var result = e.target.result;
        if(!!result == false)
          return;

        renderRecord(result.value);
        result.continue();
      };

      cursorRequest.onerror = HTML5DB.indexedDB.onerror;
    };

    function renderRecord(record) {

        $("#dbRecords").find('tbody')
            .append($('<tr>')
                .append($('<td>')
                    .append($('<span>')
                        .html(record.value)
                    )
                )
                .append($('<td>')
                    .append($('<span>')
                        .html(record.timeStamp)
                    )
                )
                .append($('<td>')
                    .append($('<a>')
                        .attr('href', 
                              'javascript:HTML5DB.indexedDB.deleteRecord(' + record.id + ')')
                        .html('Delete')
                )
            ));
    }
        


Here is the result of this code in the client side:



Finally we have implemented this call to the server to retrieve a collection of json objects and preload the database:

 
    function getData() {

        $.ajax({
            url: "application.aspx/getData",
            type: "POST",
            data: {},
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (json) {

                var records = json.d.Data.records;

                for (var i = 0; i < records.length; i++) {

                    HTML5DB.indexedDB.addRecord(records[i].Data.value);
                }
            },
            error: function (e) {
                alert('ERROR: ' + e.status + ' : ' + e.statusText);
            }
        });
    }
        


    
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public static JsonResult getData()
    {
        List<JsonResult> recordSet = new List<JsonResult>();

        for (int i = 0; i < 10; i++)
        {
            Record rec = new Record();
            rec.value = "record " + i.ToString();
            recordSet.Add(new JsonResult() { Data = rec });
        }

        JsonResult result = new JsonResult();
        result.Data = new Result() { records = recordSet };
        return result;
    }

    private class Result
    {
        public List<JsonResult> records;
    }

    private class Record
    {
        public string value;
    }
        





<METHOD SOFTWARE © 2014>

Sunday, January 24, 2016

Windows Services

Windows Services are applications that run in the background, performing diverse tasks and designed not to require user intervention

In this example, we are going to deploy a Windows Service which detects changes on a .txt file and will take its data to a database

The first step is begin a Windows Service Project



The code template of the Windows Service is as follows


namespace WSWatcher
{
    public partial class Service1 : ServiceBase
    {
        public SWatcher()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
        }

        protected override void OnStop()
        {
        }
    }
}
    


Now we add a .config file with the path of the archive to watch, and the connection string to the database

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="file_path" value="C:\ExampleData" />
  </appSettings>
  <connectionStrings>
    <add name="conSet" providerName="System.Data.SqlClient" 
         connectionString="Data Source=***; Initial Catalog=PRODUCTS; User=***; Pwd=***"/>
  </connectionStrings>
</configuration>


We add the FileSystemWatcher class to our code, and implement handlers for Created and Changed Events


protected override void OnStart(string[] args)
{
    fileWatcher = new FileSystemWatcher(ConfigurationManager.AppSettings["file_path"]);
    fileWatcher.Filter = "*.txt";
    fileWatcher.EnableRaisingEvents = true;
    fileWatcher.Changed += new FileSystemEventHandler(fileWatcher_Changed);
    fileWatcher.Created += new FileSystemEventHandler(fileWatcher_Created);
}

void fileWatcher_Created(object sender, FileSystemEventArgs e)
{
    bulkData(e.ChangeType);
}

void fileWatcher_Changed(object sender, FileSystemEventArgs e)
{
    bulkData(e.ChangeType);
}

void bulkData(WatcherChangeTypes changeType)
{
    string[] lines = System.IO.File.ReadAllLines(fileWatcher.Path + "\\data.txt");

    using (SqlConnection connection = 
    new SqlConnection(ConfigurationManager.ConnectionStrings["conSet"].ConnectionString))
    {
        connection.Open();
        foreach (string line in lines)
        {
            SqlCommand comm = connection.CreateCommand();
            comm.CommandType = CommandType.StoredProcedure;
            comm.CommandText = changeType == WatcherChangeTypes.Created
                ? "INSERT_PRODUCT"
                : "UPDATE_PRODUCT";
            comm.Parameters.Add(new SqlParameter("@idproduct", 
                Convert.ToInt32(line.Split('-')[0])));
            comm.Parameters.Add(new SqlParameter("@pname", line.Split('-')[1]));
            comm.ExecuteNonQuery();
        }
    }
}
    


It's time to create the installer for the service, right click on the service designer and add a new installer



Select serviceInstaller1 on the designer, and make sure the ServiceName property is set to SWatcher

Now click serviceProcessInstaller1 and set the Account property to LocalSystem. This will cause the service to be installed and to run on a local service account.

To build your project, before set the Startup object to point to your service. In Project Properties, on the Application page, from the Startup object list, click SWatcher.Program



Now build the solution, run Developer Command Prompt as Administrator, navigate to your bin folder, and type the command for installing the service

installutil.exe SWatcher.exe




Check the Service in the Control Panel, with the configuration specified in development, LocalSystem Account

Now we test the service, creating a file with the next data



The result is immediately appreciated

A change in the file will produces the next result



<METHOD SOFTWARE © 2012>