Posts

....
Technical Blog for .NET Developers ©

Wednesday, July 17, 2019

WCF One Way Dual Methods

WCF Services can declare methods which are invoked in one way mode, this implies the method will be called but the client side will not expect a reply, so will continue its operations without time leaks waiting for a response. This configuration is optimal for operations which don't require feedback results

OneWay methods can be bi-directionals, through a dual configuration, allowing client and server initiate invocation calls to each other. This mechanism is very useful for long-running processes in case the client expects a reply

In this post we develop a dual communication through a wsDualHttpBinding endpoint. These are the key points of the mechanism:

  • The service will expose an interface with the definition of the callback method, this method will be also marked as OneWay
  • This interface will be implemented in the client side
  • The OneWay method in the service will use this implementation to communicate with the client side once finish tasks
  • The client side must not dispose the InstanceContext with the server til the communication ends, the callback from the server will be treated as an event


The first step will be the definition of the interface in the service

    
    [ServiceContract(CallbackContract = typeof(IBookServiceCallBack))]
    public interface IBookService
    {
        [OperationContract]
        int AddBook(string title, string isbn, string synopsis, int idAuthor);

        [OperationContract]
        int AddAuthor(string firstName, string lastName, string biography);

        [OperationContract(IsOneWay = true)]
        void SendNewTitlesToSubscriptors(DateTime booksAddedAfterDate);
    }
    


And this is the definition of IBookServiceCallBack


    [ServiceContract] 
    public interface IBookServiceCallBack
    {
        [OperationContract(IsOneWay = true)]
        void NotifyClient(string message);
    }
    


We will focus on the method SendNewTitlesToSubscriptors, which will invoke the notification event on the client side

    
    public void SendNewTitlesToSubscriptors(DateTime booksAddedAfterDate)
    {
        _subscriptorManager.SendNewTitlesToSubscriptors(booksAddedAfterDate);

        INotificationServiceCallBack notificationSend =
            OperationContext.Current.GetCallbackChannel();

        notificationSend.NotifyClient(string.Format(
            "New titles added since {0} have been sent successfully", booksAddedAfterDate));
    }
    


With this configuration the client reference will add the interface IBookServiceCallBack

      <service name="BookService.BookService">
        <endpoint address="CallBackService" 
        binding="wsDualHttpBinding" contract="BookService.IBookService"/>
      </service>


Now the code in the client side:


    private InstanceContext instance
    {
        get { return new InstanceContext(new BookStoreNotificationHandler()); }
    }

    private BookServiceClient client
    {
        get { return new BookServiceClient(instance); }
    }

    private void btnSendNewTitles_Click(object sender, RoutedEventArgs e)
    {
        DateTime booksAddedAfterDate = dpBooksAddedFromDate.SelectedDate.Value;

        Thread threadSendNewTitles = new Thread(() =>
            {                    
                lblSendStep.SetContent("Sending new titles, please wait...");

                client.SendNewTitlesToSubscriptors(booksAddedAfterDate);
            });

        threadSendNewTitles.Start();
    }
    


and the implementation of IBookServiceCallBack as an event handler:

    
    public class BookStoreNotificationHandler : IBookServiceCallback
    {
        public void NotifyClient(string message)
        {
            MainWindow.lblSendStep.SetContent(message);
        }
    }
    


* Notice that in both cases we have used the extension method SetContent in order to control the content of the components in threading, as specified in this post: WPF MainWindow Instance

The result of this mechanism is the next:





<METHOD SOFTWARE © 2016>

Tuesday, October 2, 2018

Stopwatch of System.Diagnostics

For the sake of performance, the response times of many processes should be tested

The namespace System.Diagnostics exposes diverse classes for this purpose, one of them is the class StopWatch, this class represents a stopwatch to measure the time delay of the synchronous processes

We can browse the code up to its definition, exposed below

     
    public class Stopwatch
    {
        public static readonly long Frequency;
        public static readonly bool IsHighResolution;
        public Stopwatch();
        public TimeSpan Elapsed { get; }
        public long ElapsedMilliseconds { get; }
        public long ElapsedTicks { get; }
        public bool IsRunning { get; }
        public static long GetTimestamp();
        public void Reset();
        public void Restart();
        public void Start();
        public static Stopwatch StartNew();
        public void Stop();
    }
    


In this example we are working on an Oracle database invoking a stored procedure to update all records in a table, and we need to know with high precission how much time it delays when it´s called from our web site

We have data of our Contacts and the next stored procs to retrieve and update the whole table

     
  create or replace
  PROCEDURE P_SELECT_CONTACTS
    (RES OUT PKG_CONTACTS.CURSOR_ALL)
  IS
  BEGIN
  
    OPEN RES FOR SELECT FirstName "First Name", LastName "Last Name", 
      Phone "Phone", EMail "E Mail", PreferredContactForm "Preferred Contact Form" 
    FROM C_CONTACTS
    ORDER BY FirstName, LastName;
    
    RETURN;
  
  END P_SELECT_CONTACTS;
  
  --
  
  create or replace
  PROCEDURE P_UPDATE_CONTACT_FORM
    (v_ContactForm C_CONTACTS.PreferredContactForm%TYPE,
     v_RecordsAffected OUT NUMBER)
  IS
  BEGIN
  
    UPDATE C_CONTACTS SET PreferredContactForm = v_ContactForm;
    v_RecordsAffected := sql%rowcount;
    
  END P_UPDATE_CONTACT_FORM;


In our web site this is the display



Now we update the table through the next code

     
using (connection = new OracleConnection(ConfigurationManager.ConnectionStrings["csMethod"].ConnectionString))
{
    System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
    stopWatch.Start();

    connection.Open();
    OracleCommand command = connection.CreateCommand();
    command.CommandType = CommandType.StoredProcedure;
    command.CommandText = "P_UPDATE_CONTACT_FORM";
    OracleParameter pContactForm = new OracleParameter("v_ContactForm", OracleType.VarChar);
    pContactForm.Direction = ParameterDirection.Input;
    pContactForm.Value = ddContactForm.SelectedValue;
    OracleParameter pRecordsAffected = new OracleParameter("v_RecordsAffected", 
            OracleType.Number);
    pRecordsAffected.Direction = ParameterDirection.Output;

    command.Parameters.AddRange(new OracleParameter[] { pContactForm, pRecordsAffected });
    command.ExecuteNonQuery();

    Int64 recordsAffected = Convert.ToInt64(pRecordsAffected.Value);

    lblResult.Text = recordsAffected.ToString() + " records affected";

    stopWatch.Stop();
    string elapsedTime = stopWatch.Elapsed.ToString(@"mm\:ss\.ffff");

    lblStopWatch.Text = "Elapsed time: " + elapsedTime;
}


And the result is the next



As you can see, we have a measurement of round-trip time very accurate

<METHOD SOFTWARE © 2012>

Friday, August 17, 2018

Oracle Transactions

When we have a web application with an open connection to a database, in this case Oracle 11G, we have to improve the calls to the db server, and keep the ACID rules (Atomicity, Consistence, Isolation, and Durability) of the database

We have the next scenario, a web form for sumbit a new customer of our book store and all his preferences marked

In our SQL Developer, this is the schema



and the code neccessary for accomplish this task is as follows

     
create or replace
PACKAGE PKG_BOOKSTORE AS
  TYPE CURSOR_ALL IS REF CURSOR;
  PROCEDURE P_SELECT_GENRES;
  PROCEDURE NEW_CUSTOMER;
  PROCEDURE NEW_PREFERENCE;
END;

-- 

create or replace
PROCEDURE P_SELECT_GENRES
  (RES OUT PKG_BOOKSTORE.CURSOR_ALL)
IS
BEGIN

  OPEN RES FOR SELECT IdGenre, Genre FROM T_GENRES;
  
  RETURN;

END P_SELECT_GENRES;

--

create or replace
PROCEDURE NEW_CUSTOMER
  (v_FirstName IN T_CUSTOMERS.FirstName%TYPE, 
   v_LastName IN T_CUSTOMERS.LastName%TYPE,
   v_IdCustomer OUT T_CUSTOMERS.IdCustomer%TYPE)
IS BEGIN

  SELECT sqCustomers.NextVal INTO v_IdCustomer FROM DUAL;
  
  INSERT INTO T_CUSTOMERS VALUES (v_IdCustomer, v_FirstName, v_LastName);
  EXCEPTION
    WHEN DUP_VAL_ON_INDEX THEN
     RAISE_APPLICATION_ERROR(SQLCODE, 'Cannot insert duplicate value - ' + SQLERRM);
    WHEN OTHERS THEN
     RAISE_APPLICATION_ERROR(SQLCODE, SQLERRM);

END NEW_CUSTOMER;

-- 

create or replace
PROCEDURE NEW_PREFERENCE
  (v_IdCustomer IN T_CUSTOMERS.IdCustomer%TYPE, v_IdGenre IN T_GENRES.IdGenre%TYPE)
IS BEGIN

  INSERT INTO T_CUSTOMERS_GENRES VALUES (v_IdCustomer, v_IdGenre);

  EXCEPTION
    WHEN DUP_VAL_ON_INDEX THEN
     RAISE_APPLICATION_ERROR(SQLCODE, 'Cannot insert duplicate value - ' + SQLERRM);
    WHEN OTHERS THEN
     RAISE_APPLICATION_ERROR(SQLCODE, SQLERRM);
      
END NEW_PREFERENCE;


Now we include code to display all genres and get ready the form to submit a new customer

     
    private void displayGenres()
    {
        try
        {
            OracleDataReader drGenres = getGenres();

            while (drGenres.Read())
            {
                clbGenres.Items.Add(new ListItem() 
                  { Value = drGenres["IdGenre"].ToString(), 
                    Text = drGenres["Genre"].ToString() 
                  });
            }
        }
        catch (OracleException oex)
        {
            Response.Redirect("error.aspx?desc=" + oex.Message);
        }
        finally
        {
            if (connection.State == ConnectionState.Open)
                connection.Close();
        }
    }

    private OracleDataReader getGenres()
    {
        connection.Open();
        OracleCommand command = connection.CreateCommand();
        command.CommandType = CommandType.StoredProcedure;
        command.CommandText = "P_SELECT_GENRES";
        OracleDataReader dr;
        OracleParameter pRes = new OracleParameter("RES", OracleType.Cursor);
        pRes.Direction = ParameterDirection.Output;

        command.Parameters.Add(pRes);

        dr = command.ExecuteReader(CommandBehavior.SingleResult);

        return dr;
    }


and we get this result set



The next step is adding the code to call the stored procs and stablish control over the transaction

     
    private void insertCustomer()
    {
        connection.Open();
        OracleCommand cmdCustomer = connection.CreateCommand();
        OracleTransaction trax_new_customer = 
           connection.BeginTransaction(IsolationLevel.Serializable);

        try
        {
            cmdCustomer.Transaction = trax_new_customer;
            cmdCustomer.CommandType = CommandType.StoredProcedure;
            cmdCustomer.CommandText = "NEW_CUSTOMER";

            cmdCustomer.Parameters.Add(new OracleParameter
               ("v_FirstName", txtFirstName.Text));
            cmdCustomer.Parameters.Add(new OracleParameter
               ("v_LastName", txtLastName.Text));

            OracleParameter v_IdCustomer = new OracleParameter
               ("v_IdCustomer", OracleType.Int32);
            v_IdCustomer.Direction = ParameterDirection.Output;

            cmdCustomer.Parameters.Add(v_IdCustomer);

            cmdCustomer.ExecuteNonQuery();

            int IdCustomer = (int)v_IdCustomer.Value;                

            foreach (ListItem genre in clbGenres.Items)
            {
                if (genre.Selected)
                {
                    OracleCommand cmdPreference = connection.CreateCommand();

                    cmdPreference.Transaction = trax_new_customer;
                    cmdPreference.CommandType = CommandType.StoredProcedure;
                    cmdPreference.CommandText = "NEW_PREFERENCE";

                    cmdPreference.Parameters.Add(new OracleParameter
                      ("v_IdCustomer", IdCustomer));
                    cmdPreference.Parameters.Add(new OracleParameter
                      ("v_IdGenre", genre.Value));

                    cmdPreference.ExecuteNonQuery();
                }
            }

            trax_new_customer.Commit();
        }
        catch (Exception ex)
        {
            trax_new_customer.Rollback();
            Response.Redirect("error.aspx?desc=" + ex.Message);
        }
    }


The .NET Framework Data Provider for Oracle only supports ReadCommitted and Serializable isolation levels

The result with a correct execution is the following



<METHOD SOFTWARE © 2012>

Sunday, March 4, 2018

HTML5 Drag and Drop

HTML5 API includes Drag and Drop (DnD) native functionality

The event listener methods for all the drag and drop events accept Event object which has a readonly attribute called dataTransfer. The event.dataTransfer returns DataTransfer object associated with the event

This is the list of events fired during the different stages

Event Description
dragstart Fires when the user starts dragging of the object.
dragenter Fired when the mouse is first moved over the target element while a drag is occuring. A listener for this event should indicate whether a drop is allowed over this location. If there are no listeners, or the listeners perform no operations, then a drop is not allowed by default.
dragover This event is fired as the mouse is moved over an element when a drag is occuring. Much of the time, the operation that occurs during a listener will be the same as the dragenter event.
dragleave This event is fired when the mouse leaves an element while a drag is occuring. Listeners should remove any highlighting or insertion markers used for drop feedback.
drag Fires every time the mouse is moved while the object is being dragged.
drop The drop event is fired on the element where the drop was occured at the end of the drag operation. A listener would be responsible for retrieving the data being dragged and inserting it at the drop location.
dragend Fires when the user releases the mouse button while dragging an object.



In this post we develop an application to handle the drag and drop events between two elements, and launch a HttpPost method in the server which will ends inserting the dragged value in database

The first step is the definition of the UXinterface, in sequence the display is this



We are adding h5utils.js file, with an implementation of AddEvent function to simplify our code


var AddEvent = (function () {
    if (document.addEventListener) {
        return function (el, type, fn) {
            if (el && el.nodeName || el === window) {
                el.addEventListener(type, fn, false);
            } else if (el && el.length) {
                for (var i = 0; i < el.length; i++) {
                    AddEvent(el[i], type, fn);
                }
            }
        };
    } else {
        return function (el, type, fn) {
            if (el && el.nodeName || el === window) {
                el.attachEvent('on' + type, function () { return fn.call(el, window.event); });
            } else if (el && el.length) {
                for (var i = 0; i < el.length; i++) {
                    AddEvent(el[i], type, fn);
                }
            }
        };
    }
})();



Now the code to implement drag and drop events


    var pDragElement = document.createElement('p');

    var chemicalElements = document.querySelectorAll('div > p'), el = null;
    for (var i = 0; i < chemicalElements.length; i++) {

        el = chemicalElements[i];

        el.setAttribute('draggable', 'true');

        AddEvent(el, 'dragstart', dragStartElement);
        
        AddEvent(el, 'dragend', dragEndElement);        
    }

    function dragStartElement(e) {

        e.dataTransfer.effectAllowed = 'copy';
        e.dataTransfer.setData('Text', this.id);
        e.dataTransfer.setData('Type', this.innerHTML);
        
        this.style.backgroundColor = "#ffa31a";
    }
    
    function dragEndElement(e) {
        
        this.style.backgroundColor = "#fff9f0";
    }
    
    var divBoxElements = document.querySelector('#divBoxElements');

    AddEvent(divBoxElements, 'dragover', function (e) {

        if (e.preventDefault) e.preventDefault();
        e.dataTransfer.dropEffect = 'copy';
        return false;
    });

    AddEvent(divBoxElements, 'drop', function (e) {

        if (e.stopPropagation) e.stopPropagation();

        var element = e.dataTransfer.getData('Type');

        pDragElement.innerHTML = "Adding " + element + " element";

        var pClone = pDragElement.cloneNode(true);

        var newDiv = document.createElement("div");

        newDiv.appendChild(pClone);

        divBoxElements.appendChild(newDiv);

        InsertChemicalElement(element);

        return false;
    });



The function InsertChemicalElement will call the HttpPost server method


    function InsertChemicalElement(element) {
        
        var url = '@Url.Action("InsertChemicalElements", "Home")';

        $.post(url, { chemicalElement: element },
            
        function (data) {

            switch (data) {
                case 1:                    
                    divBoxElements.innerHTML = element + " inserted OK";
                    setTimeout(function() { divBoxElements.innerHTML = ""; }, 2000);
                    break;
                    
                default:
                    alert("Error inserting the element");
            }
        });
    }



The code in the server side makes use of EF, with one table and one stored procedure in the diagram



With a SOLID implementation, the code for inserting data is divided in two functions


    [HttpPost]
    public JsonResult InsertChemicalElements(string chemicalElement)
    {
        string[] elementData = chemicalElement.Split(':');

        string symbol = elementData[0].Trim();
        string name = elementData[1].Trim();

        int insertResult = _chemicalDatabase.InsertElement(symbol, name);

        return Json(insertResult);
    }


//////////


    public class ChemicalDatabase : IChemicalDatabase
    {
        public int InsertElement(string symbol, string name)
        {
            using (ChemicalsEntities entities = new ChemicalsEntities())
            {
                return entities.P_INSERT_ELEMENT(symbol, name);
            }
        }
    }


Saturday, October 14, 2017

MVC4 Multi-language

Application Resources can be created in ASP.NET applications with two different scopes, depending on the level you want to share these resources across the application

In this example we will create a set of global resources containing dictionaries for the application display in three different languages: English (en), Spanish (es), and Catalán (ca)



The application we will build is a data-entry form based on Guest model, and will be displayed in the selected language


    public class Guest
    {
        [Required(ErrorMessageResourceType = typeof(Resources.Dictionary), 
         ErrorMessageResourceName="RequiredFirstName")]
        public string FirstName { get; set; }

        [Required(ErrorMessageResourceType = typeof(Resources.Dictionary), 
         ErrorMessageResourceName = "RequiredLastName")]
        public string LastName { get; set; }

        [DataType(DataType.Date)]
        [DisplayFormat(DataFormatString = "{0:d}")]
        public DateTime? BirthDate { get; set; }
    }




We will add the next div element to the _layout.cshtml view in order to generate the language selector


    <div class="content-wrapper">
        @{
            CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture;
            string selectedLanguageStyle = "background-color:#FFDAA3;font-weight:bold;";
            <div class="float-right">                        
            @switch (currentCulture.TwoLetterISOLanguageName)
            {
                case "en":
                    <a href='@Url.Action("ChangeLanguage", 
                                            "Home", new { culture = "en-US" })'>English</a>
                    <a href='@Url.Action("ChangeLanguage", 
                                            "Home", new { culture = "es-ES" })'>Spanish</a>
                    <a href='@Url.Action("ChangeLanguage", 
                                            "Home", new { culture = "ca-ES" })'>Catalán</a>
                    break;
                case "es":
                    <a href='@Url.Action("ChangeLanguage", 
                                            "Home", new { culture = "en-US" })'>English</a>
                    <a href='@Url.Action("ChangeLanguage", 
                                            "Home", new { culture = "es-ES" })'>Spanish</a>
                    <a href='@Url.Action("ChangeLanguage", 
                                            "Home", new { culture = "ca-ES" })'>Catalán</a>
                    break;
                case "ca":
                    <a href='@Url.Action("ChangeLanguage", 
                                            "Home", new { culture = "en-US" })'>English</a>
                    <a href='@Url.Action("ChangeLanguage", 
                                            "Home", new { culture = "es-ES" })'>Spanish</a>
                    <a href='@Url.Action("ChangeLanguage", 
                                            "Home", new { culture = "ca-ES" })'>Catalán</a>
                    break;
            }
            </div>
        }
    </div>


This is the action method called from the language selectors (anchor elements), inside the HomeController


    public ActionResult ChangeLanguage(string culture)
    {
        Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
        Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture;

        Session["lang"] = culture;

        return Redirect(Request.UrlReferrer.ToString());
    }


The approach is this: we will create a BaseController to handle the ExecuteCore method, and stablish the thread's current culture. ExecuteCore method invokes the action in the current controller context. The controllers in our application will inherit BaseController


    public class BaseController : Controller
    {
        //
        // GET: /Base/

        protected override void ExecuteCore()
        {
            var culture = Session["lang"] ?? "en-US";        

            Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture.ToString());
            Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture;

            base.ExecuteCore();
        }

        protected override bool DisableAsyncSupport
        {
            get { return true; }
        }
    }


DysableAsyncSupport property gets whether to disable the asynchronous support for the controller. This flag is for backwards compatibility. ASP.NET MVC 4. allows a controller to support asynchronous patterns. This means ExecuteCore doesn't get called on derived classes. Derived classes can override this flag and set to true if they still need ExecuteCore to be called

The strongly-typed view based on Guest model is this:


@model MvcApp1.Models.Guest

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>@Resources.Dictionary.ViewTitle</h2>

<div>
    @using (Html.BeginForm())
    {
        @Html.ValidationSummary(true)
        <table>
            <tbody>
                <tr>
                    <td>
                        <div class="editor-field">
                            <span>@Resources.Dictionary.FirstName</span>
                        </div>                        
                    </td>
                    <td>
                        @Html.EditorFor(model => model.FirstName)
                        @Html.ValidationMessageFor(model => model.FirstName)                        
                    </td>
                </tr>
                <tr>
                    <td>
                        <div class="editor-field">
                            <span>@Resources.Dictionary.LastName</span>
                        </div>                        
                    </td>
                    <td>
                        @Html.EditorFor(model => model.LastName)
                        @Html.ValidationMessageFor(model => model.LastName)                        
                    </td>
                </tr>
                <tr>
                    <td>
                        <div class="editor-field">
                            <span>@Resources.Dictionary.BirthDate</span>
                        </div>                        
                    </td>
                    <td>
                        @Html.EditorFor(model => model.BirthDate)
                    </td>
                </tr>
            </tbody>
        </table>
        <input type="submit" value="Save"/>
    }    
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}


The result is the next:




<METHOD SOFTWARE © 2014>

Tuesday, May 9, 2017

Generics : Ordered Collections

Ordered Collections are correspondants collections of IEnumerable and IQueryable types

As we apply order by clauses the collections become IOrdered_

In this post we have a simple demo, intended to create a third ordered collection using the implementation of the method CreateOrderedEnumerable







Now we are creating a IOrderedQueryable collection from the first one, in its implementation of enumerable is the function of the queryable expression



Saturday, January 28, 2017

Json RPC Requests

Json RPC is becoming an extended messaging system as it is adjusted to most of actual web scenarios

Nugets for json de-serialization implement the structures to parametrize the request, we are adding Newtonsoft libraries



The method to invoke is in server side gurujsonrpc.appsoft.com, requires id and one param, and its response is a json structure with version, id, and result

The request class exposes one method returning the raw WebResponse of the invocation


    public class JsonRPCClient : HttpWebClientProtocol
    {
        public string MethodVerb { get; set; }

        public string Version { get; set; }

        public string Id { get; set; }

        public string InvokeUrl { get; set; }

        public string MethodName { get; set; }

        public object ParamsElements { get; set; }


        public WebResponse Invoke()
        {
            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(InvokeUrl);

            webRequest.ContentType = "application/json-rpc";
            webRequest.Method = MethodVerb;

            JObject message = new JObject();
            message.Add(new JProperty("jsonrpc", Version));
            message.Add(new JProperty("id", Id));
            message.Add(new JProperty("method", MethodName));

            if (ParamsElements != null)
            {
                object[] _params = new [] { ParamsElements };

                JArray _elements = new JArray();
                _elements.Add(_params);

                message.Add(new JProperty("params", _elements));
            }

            string s = JsonConvert.SerializeObject(message);
            byte[] byteArray = Encoding.UTF8.GetBytes(s);
            webRequest.ContentLength = byteArray.Length;
            Stream dataStream = webRequest.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();

            WebResponse webResponse = webRequest.GetResponse();

            return webResponse;
        }

    }


The method response returns the json object with the results


            var client = new JsonRPCClient
                {
                    InvokeUrl = "https://gurujsonrpc.appspot.com/guru",
                    MethodName = "guru.test",
                    MethodVerb = "POST",
                    Version = "2.0",
                    Id = "123",
                    ParamsElements = "Guru"
                };

            var response = client.Invoke();

            Stream responseStream = response.GetResponseStream();

            StreamReader reader = new StreamReader(responseStream);

            string result = reader.ReadToEnd();





Saturday, January 21, 2017

F# : Recursive loops

Recursive functions is one of key concepts of functional programming. F# prefix these functions with keyword rec

In this sample we have defined three functions, two of them recursives, and one of them returning a type int list. The result is the factorization of the number in parameter

Algorithm gets a lot simplified by step in the logic of factorization. This is the algorithm translated to F#



        let divide x s = (x % s) = 0

        let rec lowFactor x s = if (divide x s) then s else lowFactor x (s + 1)

        let rec factorize x =
            [
                if (x <> 1) then

                    let i = lowFactor x 2

                    yield i

                    if (divide x i) then

                        for k in factorize (x / i) do

                            yield k

            ]

        let tst = factorize 108416 


<METHOD SOFTWARE 2020 ©>

Monday, January 2, 2017

MVC4 Ajax Forms

ASP.NET MVC 4 includes Ajax functionalities based on jQuery javascript library. Most of the Ajax features in the framework build on or extend features in jQuery

In this post we will implement an asynchronous request form with validation

This is the Chemical model in our Application

 
    public class ChemicalElement
    {
        public int IdElement { get; set; }

        [DisplayName("Name")]
        [Required]
        public string Name { get; set; }

        [DisplayName("Latin name")]
        [Required]
        public string LatinName { get; set; }

        [DisplayName("Symbol")]
        [Required]
        [RegularExpression(@"\b[a-zA-Z]{1,3}\b")]
        public string Symbol { get; set; }
    }
        


We have imported the next SQL schema (table and stored procedure)



The code to release the search of chemical elements is the next


    public PartialViewResult SearchChemicalElements(string search)
    {
        var elementsModel = SearchElementsModel(search);

        return PartialView("Elements", elementsModel);
    }

    private IEnumerable<ChemicalElement> SearchElementsModel(string search)
    {
        var allElements = Elements.SearchElements(search);

        return allElements;
    }
        


And in the Elements class the implementation of the SearchElement method is this

   
	public static IEnumerable<ChemicalElement> SearchElements(string search)
    {
        using (CHEMICALSEntities context = new CHEMICALSEntities())
        {
            ObjectResult<SearchElementsBySymbol_Result> matchElements =
                context.SearchElementsBySymbol("%" + search + "%");

            foreach (var element in matchElements)
                yield return new ChemicalElement()
                {
                    IdElement = element.IdElement,
                    Name = element.Name,
                    LatinName = element.LatinName,
                    Symbol = element.Symbol
                };
        }
    }
        


The code in the View to make the process work asynchronously, is the next


@using (Ajax.BeginForm("SearchChemicalElements", "Chemical", new AjaxOptions
    {
        InsertionMode = InsertionMode.Replace,
        HttpMethod = "GET",
        LoadingElementId = "preloader",
        UpdateTargetId = "searchResults",
    }))
        


This code renders an html form with the next marks



The information about how to perform the AJAX request is contained in the DOM, and it is released by the jquery.unobtrusive-ajax.js code

The PartialView for Elements is strongly typed and renders a table in a loop for each element



The validation rules are specified in the model, so the code in the view

 
@Html.TextBoxFor(m => m.Symbol, new { Name = "search"})


will renders the information into these data dash attributes


data-val="true" 
data-val-regex="The field Symbol must match the regular expression '\b[a-zA-Z]{1,3}\b'." 
data-val-regex-pattern="\b[a-zA-Z]{1,3}\b" 
data-val-required="The field Symbol is required." 
id="Symbol" name="search"
    


The Ajax request, and validation are implemented inside the jQuery scripts

  
  @section scripts {
    <script type="text/javascript" src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
    <script type="text/javascript" src="~/Scripts/jquery.validate.min.js"></script>
    <script type="text/javascript" src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
}    


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>

Friday, December 26, 2014

Extension Methods

Extension methods are static methods, in static classes, marked up to be added to existing types without creating a new derived type, or modifying the original type. You can use extension methods to extend a class or interface. This feature was introduced in C# 3.0

In this example we will implement extension methods for two different data types: DateTime, and IEnumerable

This is the implementation of the methods in this example

 
    public static class ExtensionMethods
    {
        public static string ToLetterFormat(this DateTime dateTime)
        {
            return dateTime.ToString("MMMM d',' yyyy");
        }

        public static IEnumerable<string> GetOnlyStrings<T>(this IEnumerable<T> list)
        {
            foreach (var item in list)
            {
                if (item is string)
                    yield return item as string;
            }
        }
    }
        


The markup that makes these extension methods is the keyword this used before the first parameter in the parameter list of the method. This keyword is specific to C#, and it instructs the compiler to add the ExtensionMethodAttribute to the method

The first method produces a result like this:

  
    string letterFormatDate = (DateTime.Today).ToLetterFormat();

    Console.WriteLine(letterFormatDate);
    Console.ReadKey();
        




The second method produces this result:


 
    customList.ForEach(l => Console.WriteLine(l.GetType().ToString()));
    Console.ReadKey();

    List<string> allStringsFromCustomList = customList.GetOnlyStrings().ToList();

    Console.WriteLine(Environment.NewLine);

    allStringsFromCustomList.ForEach(s => Console.WriteLine(s));

    Console.ReadKey();
        





<METHOD SOFTWARE © 2014>

Sunday, September 14, 2014

Entity Framework Change Tracker

With ChangeTracker we can track the state of the entities in the database context, so when our processes work into a context we can work on specific group of entities

In this example we have this diagram and a class which handles the retrieve and insert methods. This is the implementation:



 
        public IEnumerable<GALAXIES> GetKnownGalaxies()
        {
            return (from GALAXIES galaxies in _context.GALAXIES select galaxies);
        }

        public void InsertGalaxy(GALAXIES galaxy)
        {
            _context.GALAXIES.Attach(galaxy);
            _context.Entry(galaxy).State = EntityState.Added;
            _context.GALAXIES.Add(galaxy);
        }
       


Now we add a third method to retrieve only the added galaxies:

     
        public IEnumerable<GALAXIES> GetNewGalaxies()
        {
            return
                (from GALAXIES galaxies in _context.ChangeTracker.Entries()
                     .Where(e => e is GALAXIES && e.State == EntityState.Added)
                     .Select(e => e.Entity as GALAXIES)
                 select galaxies);
        }

        public void InsertNewGalaxy()
        {
            GALAXIES newGalaxy = new GALAXIES()
                {
                    Name = "Cartwheel Galaxy",
                    Distance = (decimal)1.5,
                    Magnitude = (decimal)2.9
                };

            galaxyClass.InsertGalaxy(newGalaxy);
        }
    


The result of the program with this sequence is the next:

     
        var knownGalaxies = galaxyClass.GetKnownGalaxies().ToList();

        knownGalaxies.ForEach(
            x =>
            Console.WriteLine("{0}: {1} distance, {2} magnitude", 
                                x.Name, x.Distance.ToString(),
                                x.Magnitude.ToString()));

        Console.WriteLine(Environment.NewLine);
        Console.ReadKey();

        InsertNewGalaxy();

        var newGalaxies = galaxyClass.GetNewGalaxies().ToList();

        newGalaxies.ForEach(
            x =>
            Console.WriteLine("{0}: {1} distance, {2} magnitude", 
                                x.Name, x.Distance.ToString(),
                                x.Magnitude.ToString()));
    





<METHOD SOFTWARE © 2014>