Rashim's Memoir


Angular directive is a powerful feature to develop your own DOM marker that tells Angular HTML compiler to attach its functionality.  By using this feature, we could easily develop any html attributes (which we could consider as a control) that would give us to meet our business requirements. Couple of days ago I was assigned to develop a search enable input box which makes me to start developing a new directive for these purposes. Today I would like to share how I developed a new directive for search enable and autocomplete input. This is very easy and straight forward and anyone who is well-versed about angular js could easily develop this. Let’s have a bit explanation of the code,

First, the template that would use for custom input box which will work as a search input and autocomplete as well,

<div>
    <div>
        <input type="text"
               ng-keydown="handleKeyDown($event)"
               ng-model="searchText"
               ng-change="handleSearch()" />
    </div>
    <ul class="suggestions-list" ng-show="isOpen">
        <li ng-repeat="suggestion in items"
            ng-click="addToSelectedItem($index)"
            ng-mouseover="$parent.selectedIndex=$index"
            ng-class="{active : selectedIndex===$index}">{{suggestion.displayName}}</li>
    </ul>
</div>

Here, in the input box, the observable property is searchText and each time you change input value of the input text handleSearch will get executed and if there is any result it has got from its consumer to display, it just open the drop down and display the result from where we can choose.
Now the directive definition and functionality implementation,

app.directive('autoComplete', [function () {
    var autoComplete = {
        restrict: 'AE',
        scope: {
            selectedItem: "=",
            onSearch: '&'            
        },
        controller: function ($scope) {
            $scope.isOpen = false;
            $scope.selectedIndex = -1;
            $scope.searchText = '';
            $scope.items = [];          
            $scope.handleKeyDown = function (event) {
                if (event.keyCode === 40) {
                    event.preventDefault();
                    if ($scope.selectedIndex + 1 !== $scope.items.length) {
                        $scope.selectedIndex++;
                    }
                }
                else if (event.keyCode === 38) {
                    event.preventDefault();
                    if ($scope.selectedIndex - 1 !== -1) {
                        $scope.selectedIndex--;
                    }
                }
                else if (event.keyCode === 13) {
                    $scope.addToSelectedItem($scope.selectedIndex);
                    $scope.isOpen = false;
                }
            },

            $scope.handleSearch = function () {
                $scope.selectedIndex = -1;
                $scope.isOpen = false;
                $scope.items = [];
                if ($scope.searchText) {
                    var searchData = $scope.onSearch({ searchKey: $scope.searchText });
                    $scope.items = [];
                    if (searchData && searchData.length > 0) {
                        searchData.forEach(function(data) {
                            $scope.items.push(data);
                        });
                        $scope.isOpen = true;
                    } else {
                        $scope.selectedItem = $scope.searchText;
                    }
                }
            }

            $scope.addToSelectedItem = function (index) {
                $scope.selectedItem = $scope.items[index];
                $scope.searchText = $scope.selectedItem.displayName;
                $scope.isOpen = false;
            }            
        },
        templateUrl: 'autocomplete-template.html'
    };

    return autoComplete;
}]);

In this code we restrict the consumer to supply two things: one is selected Item, another one is search handler. selectedItem is needed because when you select any data from drop down ,it needs to send this data to its consumer and search handler is needed to get the search result from the consumer. That’s it; rest of the code is self-explanatory, and nothing tough as well as no extra work has been done to mention here. Source code is available here.


We usually need to develop some independent controls when we work in web or in other platform as well. This time I am going to introduce how to develop your own dropdown. We can easily use built in HTML select control but in some cases it might not fulfill our business requirements. Recently I have been working in windows 8 app where there is in need to develop a custom drop down for some of its business requirement. So I would like to share you today how to develop a custom dropdown or another controls that you would like to develop using WInJS, Html and Knockout and how to bridge those three technologies in a single hub.

If you are familiar with knockout you definitely know about how to develop custom components or if you are working with angular then you can guess it like a directive since knockout component’s is pretty much same with Angular directive. As my thought goes to use knockout, I took initiatives to develop a custom components in knockout. Here I have used using WinJS from what  I have got the flavor of OOP. But I could use raw Javascript but in this case I need to do some extra work should I want to have the taste of class based coding. Let’s move to code,

First the template that I have used for this custom drop down,

<div>
    <button class="dropdown_container" id="btnDropDown" data-bind="click:handleDropDown.bind($data)">
        <div data-bind="with: selectedItem">
            <span data-bind="text:title"></span>
        </div>
    </button>
    <div class="dropdown_bottom_frame" id="dropDownFlyout" data-win-control="WinJS.UI.Flyout" data-win-options="{ _sticky: false}">
        <div data-bind="foreach:items">
            <div data-bind="template: {name:$parent.itemTemplate}"></div>
        </div>
    </div>
</div>

There is nothing to explain about this template code since this is pretty straight forward. Here I have used WinJS Flyout for drop down and the data for this control has been bind from its controller.

The controller,

(function () {
    var dropdownController = WinJS.Class.define(function(params, element) {
        var self = this;
        var flyout = document.getElementById("dropDownFlyout");
        var anchor = document.getElementById("btnDropDown");
        this.items = params.items;
        this.selectedItem = params.selectedItem;
        this.isOpen = ko.observable(false);
        this.itemTemplate = params.itemTemplate;
        this.isOpen.subscribe(function(newValue) {
            if (newValue) {
                flyout.winControl.show(anchor, "bottom", "center");
            } else {
                flyout.winControl.hide();
            }
        });

        flyout.addEventListener("afterhide", function() {
            self.isOpen(false);
        });

        WinJS.UI.processAll().done();
    }, {
        handleDropDown: function() {
            this.isOpen(!this.isOpen());
        },
        selectItem: function(item) {
            this.selectedItem(item);
            this.handleDropDown();
        }
    }, null);
    WinJS.Namespace.define("Rashim.RND.Controls", {
        DropdownController: dropdownController        
    });
})();

In that code I have just taken the flyout control and manually drop and down it through code. Some functions have been given here to handle for its selection mode and passing data to its consumer. Through the params I have got the collections and selected item object so that I could propagate selected Item to the consumer.

And this is the component definition which define its ViewModel and template,

define(['text!./dropdownView.html'], function (htmlTemplate) {
    var viewModel = Rashim.RND.Controls.DropdownController;
    return {
        viewModel: {
            createViewModel: function (params, componentInfo) {
                return new viewModel(params, componentInfo.element);
            }
        },
        template: htmlTemplate
    };
});

I have used here require JS for lazy loading and text is an AMD loader for require to load text resource in my case which is template.

That’s it, Now the consumer consume it on it’s in any dom inside,

<dropdown params="{items:items,selectedItem:selectedItem,itemTemplate:'dropdown-template'}"></dropdown>

Here Items and selected item are the observable property of the ViewModel of the consumer and the control will get those through its params.

Enjoy!!! Source code is available here


Getting instant response on the error in an input gives the user a better familiarity on how to precise it. Validation service is very handy to do that, and almost all controls have their own validation service. But sometime we require developing our own validation service to notify user that what input it might require, and it is very easy to inject our own validation to any control using Angular JS. Today I am going to introduce you with such custom validation technique using angular JS and its feature sets.

When we work with the date field we might be in situation to validate a date range that is to say that one date should be less than other date or vice versa. To implement such functionality I have written a small directive which provides this competence to us.

The following directive could be used to check that the date is lower than other date,

 
app.directive('dateLowerThan', ["$filter", function ($filter) {
    return {
        require: 'ngModel',
        link: function (scope, elm, attrs, ctrl) {           
            var validateDateRange = function (inputValue) {
                var fromDate = $filter('date')(inputValue, 'short');
                var toDate = $filter('date')(attrs.dateLowerThan, 'short');
                var isValid = isValidDateRange(fromDate, toDate);
                ctrl.$setValidity('dateLowerThan', isValid);
                return inputValue;
            };

            ctrl.$parsers.unshift(validateDateRange);
            ctrl.$formatters.push(validateDateRange);
            attrs.$observe('dateLowerThan', function () {
                validateDateRange(ctrl.$viewValue);
            });
        }
    };
}]);
 

Here we see that there are two new things: $parser and $formatters. While we need to write a custom validation we have to write a directive which would be dependent on the ng-model directive, and $parsers and $formatters is used to hook up the custom validation logic. When the value in the control is modified the functions added to $parsers are called, and the functions added to $formatters are invoked when the model is modified in the code.The $formatters are useful when there is a possibility of the value getting changed from the code. You will get an better idea if you go through this link

Same way, the following directive could be used to check whether a date is greater than other,

 
app.directive('dateGreaterThan', ["$filter", function ($filter) {
    return {
        require: 'ngModel',
        link: function (scope, elm, attrs, ctrl) {            
            var validateDateRange = function (inputValue) {
                var fromDate = $filter('date')(attrs.dateGreaterThan, 'short');
                var toDate = $filter('date')(inputValue, 'short');
                var isValid = isValidDateRange(fromDate, toDate);
                ctrl.$setValidity('dateGreaterThan', isValid);
                return inputValue;
            };

            ctrl.$parsers.unshift(validateDateRange);
            ctrl.$formatters.push(validateDateRange);
            attrs.$observe('dateGreaterThan', function () {
                validateDateRange(ctrl.$viewValue);

            });
        }
    };
}]);
 

The utility function that has been used here,

 
var isValidDate = function (dateStr) {
    if (dateStr == undefined)
        return false;
    var dateTime = Date.parse(dateStr);

    if (isNaN(dateTime)) {
        return false;
    }
    return true;
};

var getDateDifference = function (fromDate, toDate) {
    return Date.parse(toDate) - Date.parse(fromDate);
};

var isValidDateRange = function (fromDate, toDate) {
    if (fromDate == "" || toDate == "")
        return true;
    if (isValidDate(fromDate) == false) {
        return false;
    }
    if (isValidDate(toDate) == true) {
        var days = getDateDifference(fromDate, toDate);
        if (days < 0) {
            return false;
        }
    }
    return true;
};
 

And finally the module and controller,

 
var app = angular.module("Main_app", ['ui.bootstrap']);

app.controller("MainController", ["$scope", function ($scope) {
    var currentDate = new Date();
    $scope.FromDate = new Date();
    $scope.ToDate = currentDate.setDate(currentDate.getDate() + 1);
    $scope.dateOptions = {
        formatYear: 'yy',
        startingDay: 1
    };
    $scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
    $scope.format = $scope.formats[0];
}]);
 

Files that you need to include,

angular.min.js

jquery.min.js

jquery-ui.min.js

ui-bootstrap.min.js

ui-bootstrap-tpls.min.js

And in html body you could use this directive like the way,


<div ng-controller="MainController">
        <form name="frmDateRange" novalidate>
            <div style="height: 400px">
                <div class="col-md-12 marginBottom15">
                    <label class="col-md-3 control-label">
                        From date
                    </label>
                    <div class="col-md-5">
                        <input type="text"
                            name="fromDate"
                            class="form-control"
                            datepicker-popup="{{format}}"
                            ng-model="FromDate"
                            datepicker-options="dateOptions"
                               required 
                            date-lower-than="{{ToDate| date:'short'}}" />
                    </div>
                    <div class="col-md-4 offset0">
                        <span 
                            ng-show="frmDateRange.fromDate.$error.required && 
                            !frmDateRange.fromDate.$pristine">
                            Invalid or Empty from date
                        </span>
                        <span
                            ng-show="frmDateRange.fromDate.$error.dateLowerThan">
                            From date must be lower than To date
                        </span>
                    </div>
                </div>
                <div class="col-md-12 marginBottom15">
                    <label class="col-md-3 control-label">
                        To date
                    </label>
                    <div class="col-md-5">
                        <input type="text"
                            name="endDate"
                            class="form-control"
                            datepicker-popup="{{format}}"
                            ng-model="ToDate"
                            min="FromDate"
                            datepicker-options="dateOptions"
                               required 
                            date-greater-than="{{FromDate| date:'short'}}" />
                    </div>
                    <div class="col-md-4 offset0">
                        <span 
                            ng-show="frmDateRange.endDate.$error.required 
                            && !frmDateRange.endDate.$pristine">
                            Invalid or Empty to date
                        </span>
                        <span 
                            ng-show="frmDateRange.endDate.$error.dateGreaterThan">
                            To date must be greater than from date
                        </span>
                    </div>
                </div>
            </div>
        </form>
    </div>
 

That’s it. Now play with this. The source code is available here.


Almost all web based projects, where location/address is included, we might require mapping service to show the exact location or street view on the page. Thanks to Google to give us such amazing service application, yes I am talking about Google Maps which offers street maps and street view perspective and many more. To get the map rendered in the web page using Angular JS is pretty easy and straight forward. I am going to show you how we can do this,

For this is so, I have created a directive so that I could reuse it throughout the application as an html tag. To locate the area, we might put its Latitude and Longitude or we might put just a valid address. The following directive could be used while we have the latitude and longitude for a particular area,


app.directive('areaBasedGoogleMap', function () {
    return {
        restrict: "A",
        template: "<div id='areaMap'></div>",
        scope: {           
            area: "=",
            zoom: "="
        },
        controller: function ($scope) {
            var mapOptions;
            var map;           
            var marker;

            var initialize = function () {                                
                mapOptions = {
                    zoom: $scope.zoom,
                    center: new google.maps.LatLng(40.0000, -98.0000),
                    mapTypeId: google.maps.MapTypeId.TERRAIN
                };
                map = new google.maps.Map
(document.getElementById('areaMap'), mapOptions); }; var createMarker = function (area) { var position = new google.maps.LatLng
(area.Latitude, area.Longitude); map.setCenter(position); marker = new google.maps.Marker({ map: map, position: position, title: area.Name }); }; $scope.$watch("area", function (area) { if (area != undefined) { createMarker(area); } }); initialize(); }, }; });

And this directive might be used while we have a valid address,


app.directive('addressBasedGoogleMap', function () {
    return {
        restrict: "A",
        template: "<div id='addressMap'></div>",
        scope: {
            address: "=",
            zoom: "="
        },
        controller: function ($scope) {
            var geocoder;
            var latlng;
            var map;
            var marker;
            var initialize = function () {
                geocoder = new google.maps.Geocoder();
                latlng = new google.maps.LatLng(-34.397, 150.644);
                var mapOptions = {
                    zoom: $scope.zoom,
                    center: latlng,
                    mapTypeId: google.maps.MapTypeId.ROADMAP
                };
                map = new google.maps.Map
(document.getElementById('addressMap'), mapOptions); }; var markAdressToMap = function () { geocoder.geocode({ 'address': $scope.address },
function (results, status)
{ if (status == google.maps.GeocoderStatus.OK) { map.setCenter(results[0].geometry.location); marker = new google.maps.Marker({ map: map, position: results[0].geometry.location }); } }); }; $scope.$watch("address", function () { if ($scope.address != undefined) { markAdressToMap(); } }); initialize(); }, }; });

And in html we can use these directives like the way,

<div address-based-google-map address="Adress" zoom="16"></div>
<div area-based-google-map area="Area" zoom="8"></div>

Finally Module and Controller definition,


var app = angular.module("Main_app", []);

app.controller("MainController", ["$scope", 
function MainController($scope) 
{    
    $scope.Adress = "American University,4400 Massachusetts Ave NW,Washington, DC 20016";
    $scope.Area = { 
                    Name: "Melbourne", 
                    Latitude: -37.8140000, 
                    Longitude: 144.9633200 
                  };
}]);

One more thing, you need to include following JS file to your html page,


angular.js
https://maps.googleapis.com/maps/api/js?sensor=false 

And the style,


 #areaMap, #addressMap
  {
    height: 400px;
    width: 400px;
    margin: 10px;
    padding: 10px;
  }

Very easy stuff but effective enough!!! Download Source Code


After a huge gap, I have started working in web arena again. I had been working in desktop zone for recent few years on the technologies WPF/WCF, but, now here I am to dig down again with JavaScript and its rich set of open source libraries. While playing with some other JS Libraries, I have stunned to see the power of AngularJS and I am becoming a very good fan of it.  For this is so, I am about to write a small piece of things using AngularJS and would eager to continue with it more from now on. Since I had been working on MVVM pattern in WPF, AngularJS seems to me very much similar with the idea that I had been used to in WPF. However, I would love the way AngularJS gives us the features and its continuous growing.

AngularJS is a MV* framework for dynamic web apps which outlines abundant new concepts to properly manage our web application. It enhances HTML by incorporating new ideas which is called directives that could attach in our web pages with new attributes or tags. And by using those directives we can define very powerful templates directly in our HTML. Today I am going to introduce with such thing that is custom directives for Multi Select Drop Down.

Let’s move into code,


app.directive('dropdownMultiselect', function () {
    return {
        restrict: 'A',
        scope: {
            items: "=",
            selectedItems: "="
        },
        template:"<div class='dropdown col-md-1 offset0 margintLeft15 marginRigth5'                is_open='status.open'>" +
"<button type='button' class='btn btn-success dropdown-toggle' ng-click='openDropdown($event)'>" +
"Add <span class='caret'></span>" +
"</button>" +
"<div class='dropdown-menu expertDropList' >" +
"<div class='col-md-12 marginBottom15'>" +
"<div class='pull-right'>" +
"<button class='btn btn-sm btn-success' ng-click='closeDropDown()'>Close</button>" +
"<button class='btn btn-sm btn-success' ng-click='selectAll($event)'>Check All</button>" +
"<button class='btn btn-sm btn-success' ng-click='deselectAll($event);'>Uncheck All</button>" +
"</div>" +
"</div>" +
"<div data-ng-repeat='item in items' class='expertDropListBox' ng-click='handleClick($event)'>" +
"<input type='checkbox' ng-model='item.IsSelected' ng-click='clickItem($event)' ng-change='selectItem(item)' />" +
"{{item.Name}}" +
"</div>" +
"</div>" +
"</div>",
        controller: function ($scope) {
            $scope.handleClick = function ($event) {
                $event.stopPropagation();
            };
            $scope.status = {
                isopen: false
            };
            $scope.status = { isopen: false };
            $scope.openDropdown = function ($event) {
                if ($scope.items != undefined && $scope.items.length > 0) {
                    for (var index = 0; index < $scope.items.length; index++) {                         $scope.items[index].IsSelected = false;                     }                     if ($scope.selectedItems != undefined && $scope.selectedItems.length > 0) {
                        for (var selectedItemIndex = 0; selectedItemIndex < $scope.selectedItems.length; selectedItemIndex++) {
                            for (var itemIndex = 0; itemIndex < $scope.items.length; itemIndex++) {
                                if ($scope.selectedItems[selectedItemIndex].Id == $scope.items[itemIndex].Id) {
                                    $scope.items[itemIndex].IsSelected = true;
                                    break;
                                }
                            }
                        }
                    }
                }
                $event.stopPropagation();
                $scope.status.isopen = true;
            };
            $scope.selectAll = function ($event) {
                $scope.selectedItems = [];
                angular.forEach($scope.items, function (item) {
                    item.IsSelected = true;
                    $scope.selectedItems.push(item);
                });
                $event.stopPropagation();
            };
            $scope.deselectAll = function ($event) {
                angular.forEach($scope.items, function (item) {
                    item.IsSelected = false;
                });
                $scope.selectedItems = [];
                $event.stopPropagation();
            };
            $scope.selectItem = function (item) {
                if (item.IsSelected == false) {
                    for (var index = 0; index < $scope.selectedItems.length; index++) {
                        if (item.Id == $scope.selectedItems[index].Id) {
                            item.IsSelected = false;
                            $scope.selectedItems.splice(index, 1);
                            break;
                        }
                    }
                } else {
                    $scope.selectedItems.push(item);
                }
            };
            $scope.clickItem = function ($event) {
                $event.stopPropagation();
            };
            $scope.closeDropDown = function () {
                $scope.status.isopen = false;
                $event.stopPropagation();
            };
        }
    };
});

Though the code is self-explanatory I would like to explain a bit so that anyone can easily understand the technique behind this is. In order to make a directive, first, we need to set up ‘restirct’ which means how we would use this directive; would that be used as an element or attribute or comments; in my case this is ‘A’ that is it could be used as an attributes. Next, I define the isolated scope and define two properties ‘items’ and ‘selectedItems’ which will be filled up from the controller where  it has been used. And the responsibility of this directive is to give its parent controller to the selected Items. The template defines its look and the controller contains all the logic related to the templates binding property and its event stuffs that is we can think this controller as the presenter of the template. So, we can use this directive like in our HTML page like,


<div dropdown-multiselect="" items="FirstItems" selected-items="FirstSelectedItems"></div>
<div dropdown-multiselect="" items="SecondItems" selected-items="SecondSelectedItems"></div>

Now Module and Controller definition,


var app = angular.module('myApp', ['ui.bootstrap']);

app.controller('AppCtrl', ["$scope", function ($scope) {
    $scope.status = {
        isopen: false
    };

    $scope.FirstItems = [{ Id: 1, Name: "A", IsSelected: false },
            { Id: 2, Name: "B", IsSelected: false },
              { Id: 3, Name: "C", IsSelected: false },
                { Id: 4, Name: "D", IsSelected: false },
                  { Id: 5, Name: "E", IsSelected: false },
                    { Id: 6, Name: "F", IsSelected: false },
                      { Id: 7, Name: "G", IsSelected: false },
                        { Id: 8, Name: "H", IsSelected: false}];
    $scope.FirstSelectedItems = [];

    $scope.SecondItems = [{ Id: 1, Name: "A", IsSelected: false },
            { Id: 2, Name: "B", IsSelected: false },
              { Id: 3, Name: "C", IsSelected: false },
                { Id: 4, Name: "D", IsSelected: false },
                  { Id: 5, Name: "E", IsSelected: false },
                    { Id: 6, Name: "F", IsSelected: false },
                      { Id: 7, Name: "G", IsSelected: false },
                        { Id: 8, Name: "H", IsSelected: false}];
    $scope.SecondSelectedItems = [];

    var removeItem = function (items, item) {
        for (var index = 0; index < items.length; index++) {
            if (item.Id == items[index].Id) {
                item.IsSelected = false;
                items.splice(index, 1);
                break;
            }
        }
    };
    $scope.removeFirstItem = function (item) {
        removeItem($scope.FirstSelectedItems, item);
    };
    $scope.removeSecondItem = function (item) {
        removeItem($scope.SecondSelectedItems, item);
    };
} ]);

One more thing, you need to include the following files in your html page,

      angular.js
      ui-bootstrap-tpls-0.11.0.js
      bootstrap.min.css

That’s all. Nothing is tough or impressive here. Everything is straight forward and the code is also very easy to understand. The total code and live demo can be found in the Plunker.


There is a special data type in .Net which is called string and it is a reference type, isn’t it? Of course it is but it also behaves much like a value type. That means it can directly accept values and does not require creating an instance. Have we ever thought for a single time how could we incorporate such a feature in our own class? Well, if we really need such type of feature we can easily implement it since operator overloading gives us the planetary for these purposes.

Operator overloading is a way to implement user-defined operator to be specified for operations where one or both of the operands are of a user-defined class or struct type. It also consents us to outline how the operators work with our class and struct. There are mainly three types of overload operators called unary, binary, and conversion. But not all operators of each type can be overloaded. According to MSDN, an implicit keyword is used to declare an implicit user-defined type conversion operator. In other words, this gives the power to our C# class, which can accept any reasonably convertible data type without type casting. And such a kind of class can also be assigned to any convertible object or variable.  By using this operator we can design our class which can take a value as well. Let’s move to the code.

public class StringManipulationHelper
{
private string _value;
private static StringManipulationHelper _stringManipulationHelper;

public StringManipulationHelper()
{
_value = string.Empty;
}

public StringManipulationHelper(string submittedValue)
{
_value = submittedValue;
}

public static implicit operator StringManipulationHelper(string submittedValue)
{
_stringManipulationHelper = new StringManipulationHelper(submittedValue);
return _stringManipulationHelper;
}

public static implicit operator string(StringManipulationHelper objHelper)
{
return objHelper._value;
}
}

Now you can use in any way like this,

StringManipulationHelper helper = null;
or
StringManipulationHelper helper = "This is test";
or
var helper = new StringManipulationHelper();
or
var helper = new StringManipulationHelper("This is a Test");

Easy enough right? But it will help us a lot when we are in need such kinds of features.


As a series of article, this time, I am going to introduce you with Event-based asynchronous communication. I have used here same service operation of IAsyncResult asynchronous operation that I have mentioned earlier. Service implementation and hosting are also same with IAsyncResult asynchronous. So, in this case I will not go to explain service section again as well as will not go for in details all parts as i have discussed it clearly in other two posts. I would suggest you to have a look on the given links first.

To develop a client is just straight forward. Here I have shown you a console app as a client,

public class Program
 {
 static void Main(string[] args)
 {
 var proxy = new MessageServiceProxy("MessageServiceEndpoint");
 proxy.GetMessageCompleted += GetMessageCompleted;
 proxy.GetMessageAsync("HI");
 Console.WriteLine("waiting");
 Console.ReadLine();
 }
 static void GetMessageCompleted(object sender, GetMessageCompletedEventArgs e)
 {
 Console.WriteLine(e.Result.ToString(CultureInfo.InvariantCulture));
 }
 }

And its corresponding configuration has been given below,

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <system.serviceModel>
 <bindings />
 <client>
 <endpoint address="http://localhost/Rashim.Rnd.WCF.Asynchronous.Services/"
 binding="basicHttpBinding" contract="Rashim.Rnd.WCF.Asynchronous.Services.IMessageService"
 name="MessageServiceEndpoint">
 <identity>
 <dns value="ServerCertificate" />
 </identity>
 </endpoint>
 </client>
 </system.serviceModel>
</configuration>

Now the important thing is how we develop our ServiceProxy which in our case is MessageServiceProxy .

public class MessageServiceProxy : ClientBase<IMessageService>, IMessageService
 {
 public event EventHandler<GetMessageCompletedEventArgs> GetMessageCompleted;
 private BeginOperationDelegate _onBeginGetMessage;

private EndOperationDelegate _onEndGetMessage;

private SendOrPostCallback _onGetMessageCompleted;

public MessageServiceProxy()
 {
 }

public MessageServiceProxy(string endpointConfigurationName) :
 base(endpointConfigurationName)
 {
 }

public IAsyncResult BeginGetMessage(string message, AsyncCallback callback, object asyncState)
 {
 return Channel.BeginGetMessage(message, callback, asyncState);
 }

public string EndGetMessage(IAsyncResult result)
 {
 return Channel.EndGetMessage(result);
 }

private IAsyncResult OnBeginGetMessage(object[] inValues, AsyncCallback callback, object asyncState)
 {
 var message = ((string)(inValues[0]));
 return BeginGetMessage(message, callback, asyncState);
 }

private object[] OnEndGetMessage(IAsyncResult result)
 {
 string retVal = Channel.EndGetMessage(result);
 return new object[] {
 retVal};
 }

private void OnGetMessageCompleted(object state)
 {
 if ((GetMessageCompleted != null))
 {
 var e = ((InvokeAsyncCompletedEventArgs)(state));
 GetMessageCompleted(this, new GetMessageCompletedEventArgs(e.Results, e.Error, e.Cancelled, e.UserState));
 }
 }

public void GetMessageAsync(string message)
 {
 GetMessageAsync(message, null);
 }

private void GetMessageAsync(string message, object userState)
 {
 if ((_onBeginGetMessage == null))
 {
 _onBeginGetMessage = OnBeginGetMessage;
 }
 if ((_onEndGetMessage == null))
 {
 _onEndGetMessage = OnEndGetMessage;
 }
 if ((_onGetMessageCompleted == null))
 {
 _onGetMessageCompleted = OnGetMessageCompleted;
 }
 InvokeAsync(_onBeginGetMessage, new object[] {
 message}, _onEndGetMessage, _onGetMessageCompleted, userState);
 }
 }

Here I have used three delegates namely onBeginGetMessage, onEndGetMessage and onGetMessageCompleted and these three delegates will register when we first call GetMessageAsync() method. onGetMessageCompleted  is a SendOrPostCallback which represents a callback method that we want to execute when a message is to be dispatched to a synchronization context.

Finally the GetMessageCompletedEventArgs,

public class GetMessageCompletedEventArgs : AsyncCompletedEventArgs
 {
 private readonly object[] _results;

public GetMessageCompletedEventArgs(object[] results, Exception exception, bool cancelled, object userState) :
 base(exception, cancelled, userState)
 {
 _results = results;
 }

public string Result
 {
 get
 {
 RaiseExceptionIfNecessary();
 return ((string)(_results[0]));
 }
 }
 }

Download Source code


We are very well-versed that WCF service operations can be implemented asynchronously or synchronously .And the clients can call service operations synchronously or asynchronously since asynchronous service operations can be calling synchronously and vice versa. There are three ways to implement asynchronous operations

As a series of sequence, in this post, I am going to use IAsyncResult asynchronous operation but we should keep in mind that this pattern is no longer recommended for further development. If we know these three mechanisms of asynchronous operation it would be easier for us to architect our large distributed system based on asynchronous service. Before going to our implementation I would recommend you to have a look on APM Model first. I would like to Organize todays article in three steps; Service Implementation, Service Hosting and Client

Service Implementation

In IAsyncResult asynchronous system asynchronous operations require Begin and End methods.


[ServiceContract]
 public interface IMessageService
 {
 [OperationContract(AsyncPattern = true)]
 IAsyncResult BeginGetMessage(string message, AsyncCallback callback, object state);

string EndGetMessage(IAsyncResult asyncResult);
 }

In the service contract, I declare an asynchronous method pair according to the APM. The BeginGetMessage method takes a parameter, a callback object, and a state object, and returns an IAsyncResult while EndGetMessage method takes an IAsyncResult and returns the value. Since the service operation returns IAsyncResult we have to implement it first. And the implementation has been given below,


public class AsyncResult : IAsyncResult,IDisposable
 {
 private AsyncCallback _callback;
 private object _state;
 private ManualResetEvent _manualResetEvent;

public AsyncResult(AsyncCallback callback, object state)
 {
 _callback = callback;
 _state = state;
 _manualResetEvent = new ManualResetEvent(false);
 }

public bool IsCompleted
 {
 get { return _manualResetEvent.WaitOne(0, false); }
 }

public WaitHandle AsyncWaitHandle
 {
 get { return _manualResetEvent; }
 }

public object AsyncState
 {
 get { return _state; }
 }
 public ManualResetEvent AsyncWait
 {
 get { return _manualResetEvent; }

 }
 public bool CompletedSynchronously
 {
 get { return false; }
 }

public void Completed()
 {
 _manualResetEvent.Set();
 if (_callback != null)
 _callback(this);
 }

 public void Dispose()
 {
 _manualResetEvent.Close();
 _manualResetEvent = null;
 _state = null;
 _callback = null;
 }
 }

AsyncResult implements IAsyncResult that has some properties like AsyncCallback, state object and a ManualResetEvent, which handle waiting for asynchronous operation. IsCompleted is used to specify that the operation is completed asynchronously. In the Complete() method ManualResetEvent has been set, which means that the event is signaled now and any other awaiting thread can follow.

Now for our MessageServiceOperation I create MessageAsyncResult which just inherit from AsyncResult to add a Message property.


public class MessageAsyncResult : AsyncResult
 {
 public string Message { get; private set; }
 public MessageAsyncResult(string message, AsyncCallback callback, object state)
 : base(callback, state)
 {
 Message = message;
 }
 }

Now implementing the service operations.


public class MessageService : IMessageService
 {
 public IAsyncResult BeginGetMessage(string message, AsyncCallback callback, object state)
 {
 var replyMessage = string.Format("{0}{1}","Server says :",message);
 var messageAsyncResult = new MessageAsyncResult(replyMessage, callback, state);
 ThreadPool.QueueUserWorkItem(CompleteProcess, messageAsyncResult);

return messageAsyncResult;
 }

private void CompleteProcess(object state)
 {
 var messageAsyncResult = state as MessageAsyncResult;
 messageAsyncResult.Completed();
 }

public string EndGetMessage(IAsyncResult asyncResult)
 {
 var messageAsyncResult = asyncResult as MessageAsyncResult;
 messageAsyncResult.AsyncWait.WaitOne();
 return messageAsyncResult.Message;
 }
 }

In the BeginGetMessage () method I create an instance of MessageAsyncResult by passing appropriate parameters to it then call ThreadPool.QueueUserWorkItem() method to add a method to waiting queue for execution. The method CompleteProcess() will run whenever a thread becomes available and it finally call the Completed() method to release the thread and allow the other operations to execute. In the EndGetMessage () method, I call the WaitOne() method of its ManualResetEvent to wait until the current execution ends then return the Result property.

Service Hosting

This is also very simple. Here I have used a console app which will be used as a server,


class Program
 {
 static void Main(string[] args)
 {
 var svcHost = new ServiceHost(typeof(MessageService));
 Console.WriteLine("Available Endpoints :\n");
 svcHost.Description.Endpoints.ToList().ForEach(endpoints => Console.WriteLine(endpoints.Address.ToString()));
 svcHost.Open();
 Console.ReadLine();
 }
 }

And the configuration for that,


<configuration>
 <system.serviceModel>
 <behaviors>
 <serviceBehaviors>
 <behavior name="">
 <serviceMetadata httpGetEnabled="true" />
 <serviceDebug includeExceptionDetailInFaults="false" />
 </behavior>
 </serviceBehaviors>
 </behaviors>
 <services>
 <service name="Rashim.Rnd.WCF.Asynchronous.Services.MessageService">
 <endpoint address="" binding="basicHttpBinding" contract="Rashim.Rnd.WCF.Asynchronous.Services.IMessageService">
 <identity>
 <dns value="localhost" />
 </identity>
 </endpoint>
 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
 <host>
 <baseAddresses>
 <add baseAddress="http://localhost/Rashim.Rnd.WCF.Asynchronous.Services/" />
 </baseAddresses>
 </host>
 </service>
 </services>
 </system.serviceModel>
</configuration>

Client

Now how client could consume this service.? Here I have given a simple console app to consume this service,


public class Program
 {
 static void Main(string[] args)
 {
 var channelFactory = new ChannelFactory<IMessageService>("MessageServiceEndpoint");
 var proxy = channelFactory.CreateChannel();
 var message = Console.ReadLine();
 while (message.Equals("exit",StringComparison.CurrentCultureIgnoreCase)==false)
 {
 proxy.BeginGetMessage(message, ClientCallBack, proxy);
 message = Console.ReadLine();
 }
 }

private static void ClientCallBack(IAsyncResult ar)
 {
 var res = ar.AsyncState as IMessageService;
 if (res != null)
 {
 var message = res.EndGetMessage(ar);
 Console.WriteLine(message);
 }
 }
 }

And the configuration file for this is,


<configuration>
 <system.serviceModel>
 <bindings />
 <client>
 <endpoint address="http://localhost/Rashim.Rnd.WCF.Asynchronous.Services/"
 binding="basicHttpBinding" contract="Rashim.Rnd.WCF.Asynchronous.Services.IMessageService"
 name="MessageServiceEndpoint">
 <identity>
 <dns value="ServerCertificate" />
 </identity>
 </endpoint>
 </client>
 </system.serviceModel>
</configuration>

That’s it. Download Source code.


Last couple of months, I was in rush and could not contribute to the community as much as I have been expected, but regularly I have been answering the questions and giving solutions of different technical problems that I have got through e-mail from different know-how guys.  Solving and replying those critical problems engage me 2-3 hours a day and at the same time I have to spend 8-9 hours a day in my office, so it is really tough to allocate time for writing about something new. But, then again, it is all about our part of  life; I would come up writing with new and cutting edge technologies very soon again.

Today I would like to give a solution of a weird problem that I had confronted for deploying SQLite.

”Could not load file or assembly ‘System.Data.SQLite.dll’ or one of its dependencies.”

For solving this issue I had tried a whole variety of ways but had not got my problem solved. What I had done to solve this issue was that I installed   the version sqlite-netFx40-setup-bundle-x86-2010-1.0.89.0 and then copy the System.Data.SQLite.dll to my project folder and refer this dll to my project. It solved the problem in my development PC but when I had gone for deployment I had got another error which is like that,

“Unable to load DLL ‘SQLite.Interop.dll’: The specified module could not be found. (Exception from HRESULT: 0x8007007E)”

It shows that the native interop assembly is required either for x86 or x64 architecture. As  ‘System.Data.SQLite.dll’  is a mixed mode assembly, I suspected it would automatically loads its native code. But I had got no luck really!! The reason behind this is might be that a particular mixed mode assembly is either for x86 or x64 not for both. Anyway I really don’t know what was the exact reason inside for this issue. After trying in many different ways I had come across the solution finally. Here it is.

First we need to install SQLite and in my case I installed it from NuGet gallery.To do that you can follow the steps that have been given below:

Go to the TOOLS->Library Package Manager->Package Manager Console of the Visual studio.

Image 

  Then run the command Install-Package System.Data.SQLite

Image

Now in your project you have got two folders x86 and x64, underneath this folder you will find those SQLite.Interop.dll’. 

Image

Now go to the properties windows of those dlls and set build action is content and Copy to output directory is Copy always.

Image

Like the way you also need to change the property settings for  ‘System.Data.SQLite.dll’.

That’s it. Now build your app. You are ready to deploy and see it is working perfectly in your client machine too.


WebSocket, like as TCP, is a bi-directional, full-duplex communication channel over a single TCP connection but it shortens abundant complications close to bi-directional communication as well as connection management which we typically comprehend while using TCP. WebSocket channels start as normal HTTP channels which then upgraded to WebSocket channels by using handshaking, allowing cooperative TCP communication between client and server.

WCF hosts provision for WebSockets over the standard HTTP ports 80 and 443. The standard HTTP port allows WebSockets to communicate across the web through mediators. WCF introduces two standard bindings to support communication over a WebSocket transport.

  • NetHttpBinding
  • NetHttpsBinding

These bindings are designed for consuming WebSocket services and will perceive whether they are used with a request-reply contract or duplex contract and change their behavior according to it. They will use HTTP/HTTPS for request-reply contracts and WebSockets for duplex contracts. We can override this behavior by using WebSocketTransportUsage setting

  • Always – Enforce to use WebSockets.
  • Never – Stops to use WebSockets.
  • WhenDuplex – This is the default value.

Let’s move into the code to see how we could implement WCF service and clients that will communicate over WebSockets.

Define callback Contract

    public interface INotificationServiceCallback
    {
        [OperationContract(IsOneWay = true)]
        void OnNotificationSend(Notification notification);
    }

Clients will implement this contract through which the service can send messages back to the clients. To have a better understanding how duplex channel works I would recommend you to have a look on this link.

Define the service contract

    [ServiceContract(CallbackContract = typeof(INotificationServiceCallback))]
    public interface INotificationService
    {
        [OperationContract]
        void SendNotification(Notification notification);

        [OperationContract]
        void SubscribeForNotification(List<NotificationType> notificationTypes);

        [OperationContract]
        void UnsubscribeForNotification(List<NotificationType> notificationTypes);
    }

Here INotificationServiceCallback has been specified as the callback contract.

Implement the service contract

    public class NotificationServiceService : INotificationService
    {
        private INotificationServiceCallback Subscriber
        {
            get { return OperationContext.Current.GetCallbackChannel<INotificationServiceCallback>();  }
        }

        public void SendNotification(Notification notification)
        {
            NotificationManager.Instance.SendNotification(notification, Subscriber);
        }

        public void SubscribeForNotification(List<NotificationType> notificationTypes)
        {
            NotificationManager.Instance.AddSubscriber(Subscriber, notificationTypes);
        }

        public void UnsubscribeForNotification(List<NotificationType> notificationTypes)
        {
            NotificationManager.Instance.RemoveSubscriber(Subscriber, notificationTypes);
        }
    }

In the implementation, we retain the callback channel using the OperationContext which has been passed to the NotificationManager and finally NotificationManager does the rest of the Jobs.

Implement Notification Manager

    public class NotificationManager
    {
        private volatile static NotificationManager _notificationManager = null;
        private static readonly object SyncLock = new object();
        private NotificationManager()
        {
            Subscribers = new Dictionary<INotificationServiceCallback, List<NotificationType>>();
            Notifications = new List<Notification>();
        }

        public Dictionary<INotificationServiceCallback, List<NotificationType>> Subscribers { get; private set; }
        public List<Notification> Notifications { get; private set; }
        public static NotificationManager Instance
        {
            get
            {
                lock (SyncLock)
                {
                    if (_notificationManager == null)
                    {
                        lock (SyncLock)
                        {
                            _notificationManager = new NotificationManager();
                        }
                    }
                }
                return _notificationManager;
            }
        }

        public void AddSubscriber(INotificationServiceCallback subscriber, List<NotificationType> notificationType)
        {
            if (!Subscribers.ContainsKey(subscriber))
                Subscribers.Add(subscriber, notificationType);
            else
            {
                var newNotificationType = notificationType.Where(n => Subscribers[subscriber].Any(n1 => n1 != n));
                Subscribers[subscriber].AddRange(newNotificationType);
            }
        }

        public void RemoveSubscriber(INotificationServiceCallback subscriber, List<NotificationType> notificationTypes)
        {
            if (Subscribers.ContainsKey(subscriber))
            {
                notificationTypes.ForEach(notificationType => Subscribers[subscriber].Remove(notificationType));

                if (Subscribers[subscriber].Count < 1)
                    Subscribers.Remove(subscriber);
            }
        }

        public void AddNotification(Notification notification)
        {
            if (!Notifications.Contains(notification))
                Notifications.Add(notification);
        }

        public void RemoveNotification(Notification notification)
        {
            if (Notifications.Contains(notification))
                Notifications.Remove(notification);

        }

        public void SendNotification(Notification notification, INotificationServiceCallback sender)
        {
            foreach (var existingSubscriber in Subscribers)
            {
                if (existingSubscriber.Value.Any(n => n == notification.NotificationType) && existingSubscriber.Key != sender)
                {
                    if (((ICommunicationObject)existingSubscriber.Key).State == CommunicationState.Opened)
                    {
                        existingSubscriber.Key.OnNotificationSend(notification);
                    }
                }
            }
        }
    }

As we see, NotificationManager maintains a dictionary to hold the client list whose have been subscribed for getting the notifications for different notification types. If any client broadcast messages with Notification types, the subscribers who only subscribe to get the notification for these notification types will get these messages. The code is itself self-explanatory. If you go through on the code portion you will easily have an idea about that.

Service configuration

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.web>
     <compilation debug="true" targetFramework="4.5" />
     <httpRuntime targetFramework="4.5" />
  </system.web>
   <system.serviceModel>
        <protocolMapping>
          <add scheme="http" binding="netHttpBinding" />
        </protocolMapping>
        <behaviors>
            <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
    <system.webServer>
        <directoryBrowse enabled="true" />
    </system.webServer>
</configuration>

NetHttpBinding has been used for the default endpoints. If you want to acquaint a bit more about the configuration updates, I would suggest having a look on that.

Okay Service Portion has been done. Now, lets move to client portions,

Implement callback contract and Define Client

    class Program : INotificationServiceCallback
    {
        private NotificationServiceClient _notificationServiceClient;
        private InstanceContext _instanceContext;
        private readonly List<NotificationType> _notificationTypes = Enum.GetValues(typeof(NotificationType)).Cast<NotificationType>().ToList();

        public NotificationServiceClient NotificationServiceClient
        {
            get
            {
                return _notificationServiceClient ??
                       (_notificationServiceClient = new NotificationServiceClient(CallbackInstance,
                                                                                   "netHttpBinding_INotificationService"));
            }
        }

        public InstanceContext CallbackInstance
        {
            get { return _instanceContext ?? (_instanceContext = new InstanceContext(this)); }
        }

        static void Main(string[] args)
        {
            var objProgram = new Program();
            Console.WriteLine("Write exit to shut down....\n");
            Console.WriteLine("Wait...Subscribing for notifications\n");
            objProgram.SubscribeForNotification();
            Console.WriteLine("Subscription done...Now you can send notifacation\n");
            var readMsg = Console.ReadLine();

            while (readMsg.ToString(CultureInfo.InvariantCulture).ToLower().Equals("exit") == false)
            {
                objProgram.SendNotification(readMsg);
                Console.WriteLine("Notification has been send......\n");
                readMsg = Console.ReadLine();
            }
            objProgram.UnsubscribeForNotification();
        }

        public void OnNotificationSend(Notification notification)
        {
            Console.WriteLine(string.Format("New Notification Received\n\nMessage :{0}\nTime :{1}\n\n", notification.NotificationMsg, notification.PostingTime));
        }

        private void SubscribeForNotification()
        {
            NotificationServiceClient.SubscribeForNotification(_notificationTypes);
        }

        private void UnsubscribeForNotification()
        {
            NotificationServiceClient.UnsubscribeForNotification(_notificationTypes);
        }

        private void SendNotification(string msg)
        {
            NotificationServiceClient.SendNotification(new Notification()
            {
                NotificationMsg = msg,
                PostingTime = DateTime.Now
            });
        }
    }

The client application has a property of InstanceContext and NotificationServiceClient, also it specifies the implementation of the INotificationServiceCallback interface. When a client subscribes for the notifications to the service, the service will send the notifications to the client using the callback contract specified.

Implement NotificationServiceClient

    public class NotificationServiceClient : DuplexClientBase<INotificationService>, INotificationService
    {
        public NotificationServiceClient(InstanceContext callbackInstance) :
            base(callbackInstance)
        {
        }

        public NotificationServiceClient(InstanceContext callbackInstance, string endpointConfigurationName) :
            base(callbackInstance, endpointConfigurationName)
        {
        }

        public void SendNotification(Notification notification)
        {
            Channel.SendNotification(notification);
        }

        public void SubscribeForNotification(List<NotificationType> notificationTypes)
        {
            Channel.SubscribeForNotification(notificationTypes);
        }

        public void UnsubscribeForNotification(List<NotificationType> notificationTypes)
        {
            Channel.UnsubscribeForNotification(notificationTypes);
        }
    }

Client Configuration

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <netHttpBinding>
        <binding name="NetHttpBinding_INotificationService">
          <webSocketSettings transportUsage="Always" />
        </binding>
      </netHttpBinding>
    </bindings>
    <client>
      <endpoint address="ws://localhost/websocket/NotificationService.svc"
          binding="netHttpBinding"
          contract="Rashim.RND.WCF.WebSockect.Interfaces.INotificationService"
             bindingConfiguration="NetHttpBinding_INotificationService"
          name="netHttpBinding_INotificationService">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

This is as usual and not any special, what you need to do in the client configuration is to specify the client side endpoint using the NetHttpBinding.

Finally DataContracts

    [DataContract]
    public class Notification
    {
        [DataMember]
        public string NotificationMsg { get; set; }
        [DataMember]
        public DateTime PostingTime { get; set; }
        [DataMember]
        public NotificationType NotificationType { get; set; }
    }
    [DataContract]
    public enum NotificationType
    {
        [EnumMember]
        General,
        [EnumMember]
        Greetings
    }

Using Source code

You need to host the Rashim.RND.WCF.WebSockect.Services in IIS8 and then put the appropriate endpoint address to the client configuration file. After completing the Service hosting, you need to run the two instances of Rashim.RND.WCF.WebSockect.Clients then you can send message from instance to another one just like the given figure below.

WebSocketDemo
 References: 

Download SourceCode.

 

Blog Stats

  • 194,520 hits

Categories