Sony Arouje Blog

a programmer's log

Bind JSON REST result using Knockout

leave a comment »

Last couple of hours I was trying to bind json data from a WCF service to a simple HTML UI using Knockout js. This is a very simple application I created to learn Knockout. This application is also a tracer to test  whether I can bind json result from the service directly to the UI, without creating an elaborate javascript view model at the client side. In real world services returns complex json, so it’s not possible to create the same model at the client side.

ko.mapping

Knockout provides mapping as a plugin, you can see more details here. Please  go through the link before you proceed.

So let’s see how I created my view model and the html UI.

I created a js file named customerviewmodel.js and added the  below code.

function customerViewModel() {
    var self = this;

    self.customerList = ko.observableArray();

    self.getCustomers = function () {
        $.ajax({
            type: 'GET',   
            url: 'http://10.0.0.2:8081/CustomerService/customers',
            contentType: "application/javascript",
            dataType: "jsonp",
            success: function(data) {
                var observableData = ko.mapping.fromJS(data);
                var array = observableData();
                self.customerList(array);
            },
            error:function(jq, st, error){
                alert(error);
            }
        });
    };
}

$(document).ready(function () {
    ko.applyBindings(new customerViewModel());
});

And the html UI. For this tracer app, I created a MVC4 web application and removed all the html code from the Views/Home/index.cshtml and replaced it with the below code.

<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/knockout-2.2.0.debug.js"></script>
<script src="~/Scripts/knockout.mapping-latest.debug.js"></script>
<script src="~/MyScripts/customerviewmodel.js"></script>

<table>
    <thead>
        <tr>
            <th>Id</th>
            <th>Name</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: customerList">
        <tr>
            <td data-bind="text: Id"></td>
            <td data-bind="text: Name"></td>
        </tr>
    </tbody>
</table>
<br/>

<input type="button" id="btnGetCustomers" value="Get Customers" data-bind="click: getCustomers">

 

customerList is a ko.observablearray and the data will get filled when the user clicks the button. I was able to call the WCF  REST api and get the json but unable to populate customerList or show the data to the  UI.  I fixed the issue with the  help of a post from Stackoverflow, see the code snippet below.

            success: function(data) {
                var observableData = ko.mapping.fromJS(data);
                var array = observableData();
                self.customersResult(array);}
WCF Configuration changes

As you can see, my WCF REST service is running in a different machine, and when I do an ajax call with datatype:json I am getting some errors. After some googling I came to know that I have to call the service with datatype:jsonp. So I changed it to jsonp and started getting the below error.

jQuery18206380491638767738_1396378264364 was not called

 

So I modified the  WCF service configuration as shown below to work with jsonp request.

    <bindings>
        <webHttpBinding>
          <binding name="webHttpBindingJson" crossDomainScriptAccessEnabled="true" />
        </webHttpBinding>    
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServicesBehavior">
           <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webby">
          <webHttp helpEnabled="true" />
        </behavior>
      </endpointBehaviors>
    </behaviors>

I configured the service as shown below. I use a custom hosting, so need to provide baseaddresses.

    <services>
      <service name="WCFRestTest.Services.CustomerService" behaviorConfiguration="ServicesBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://10.0.0.2:8082/CustomerService/Details"/>
          </baseAddresses>
        </host>
        <endpoint name="customerServiceRest" address="http://10.0.0.2:8081/CustomerService" 
               bindingConfiguration="webHttpBindingJson" binding="webHttpBinding" 
               contract="WCFRestTest.Services.ICustomerService" behaviorConfiguration="webby"/>
      </service>
    </services>

 

After this WCF configuration changes I could able to get json from the REST  api and bind the result to html UI using Knockout.

Let me know if you have any questions.

 

Happy coding…

Written by Sony Arouje

April 2, 2014 at 12:46 am

Posted in JavaScript

Tagged with , , ,

Enable Stratus player in Tumblr

with 2 comments

I wanted to install stratus player for my site lumigraphs.com. I tried all the options mentioned in the stratus site but the stratus player is not showing in my tumblr site. I even tried with different versions of jquery and moving the script to Header section from Body, but nothing really worked.

Here is what I did to get it working, it’s very simple.

In stratus site the script to add to the body was like below.

<script type="text/javascript">

$(document).ready(function(){

$stratus({

auto_play: true,

download: false,

links: 'http://soundcloud.com/qotsa',

random: true

});

});

</script>

 

To get it working we need change it as follows and put it inside the body. Below I am giving the whole script including the jquery reference I used.

 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.js"></script>
<script type="text/javascript" src="http://stratus.sc/stratus.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    $('body').stratus({
      auto_play: true,
      download: false,
      align: 'bottom',
      links: 'https://soundcloud.com/sony-arouje/sets/fortumblr',
      random: true
    });
});
</script>
 

The only change I did was appended $(‘body’) just before calling stratus (marked in bold above).

Edit

When I put the stratus plugin in the body, tumblr is not loading all my photos, only few is showing. So I moved the above script to head, the only change is, instead of $(‘body’).stratus(… to $(‘head’).stratus…

Written by Sony Arouje

March 7, 2014 at 6:57 pm

nginx and Elasticsearch in Windows

leave a comment »

The system I was working might need more than one Elasticsearch node configured as Master or Load balancer. I wanted to come up with a logic to connect to a different node in case of node failure. That means I have to write logic to check the status of a node before sending any index or search request. If the status failed, take the next node from the configured list and check the status. This is a viable approach but more concerned about the performance impact of my logic.

I started searching for a system that can open up a proxy IP and group the elasticsearch instance’s under that ip. This way the client will be aware of this proxy ip and not the individual ip and port details of Elasticsearch nodes. Also any node failures will be handled by the proxy system. After some exploration I decided to try nginx, it has built in load balancing with very simple configuration. I downloaded the mainline version of nginx for Windows and installed it.

To modify the nginx configuration go to conf\nginx.conf and open the configuration file in any text editor and add your configuration. See my configuration below.

worker_processes  1;
events {
worker_connections  1024;
}

http {

include       mime.types;
default_type  application/octet-stream;

upstream elasticcluster{
server 192.168.11.105:9200 weight=1 fail_timeout=1;
server 192.168.11.105:9201 weight=1 fail_timeout=1;
}

sendfile        on;
keepalive_timeout  65;
server {
listen       8080;
server_name  127.0.0.1;

location / {
proxy_pass  http://elasticcluster;
proxy_connect_timeout 1;
}

error_page   500 502 503 504  /50x.html;
location = /50x.html {
root   html;
}

}
}

In the upstream I group all my Elasticsearch nodes under elasticcluster. In the server’s proxy_pass I specify the upstream name, eg. http://elasticcluster. That’s it, now I can access my elastic search node via 127.0.0.1:8080 and nginx will route the traffic to any one of my Elasticsearch node in round robin manner. As you can see nginx ip and port is configured via listen and server_name settings.

Now all my search or index request goes to nginx ip and nginx will route the traffic to any of the Elasticsearch node running in my dev machine. I test failover by stopping one of my Elasticsearch node and nginx routed the traffic to the other live nodes.

Issue with localhost

Initially I configured nginx and Elasticsearch to use different ports of localhost. This causes some huge delay in nginx to route traffic to Elasticsearch nodes. I found this post from nginx forum and realized that the issue is with localhost. So I configured all my Elasticsearch instance to use the ip address instead of localhost. Also configured nginx.conf and specify 127.0.0.1 as server_name, you can also give the IP address instead of 127.0.0.1.

Leave your comments below if you find it helpful or have any questions. Thanks for reading.

Happy coding…

Written by Sony Arouje

March 3, 2014 at 6:39 pm

Indexing and Searching with ElasticSearch

leave a comment »

Last couple of days I was experimenting with ElasticSearch and different client libraries for .NET. In this post I will detailed the implementation of Indexing and searching using ElasticSearch in .NET. For detailed documentation of Elasticsearch visit official site or Joel Abrahamsson post.

I use PlainElastic.Net as my Elastic search client. PlainElastic is a very simple lightweight library for  Elasticsearch. It uses plain json for indexing and query, this gives me more freedom and tooling to create json from the user inputs for indexing and query.

To make it more flexible, our system gets data from the database using views. Datareader class converts this data to Dynamic objects. Then converts it to json and pass it to PlainElastic for indexing. Dynamic object makes life more easier as we can reuse this class with different views without worrying about strong types. Below is the Dynamic class I created.

    public class ElasticEntity:DynamicObject
    {
        private Dictionary<string, object> _members = new Dictionary<string, object>();

        public static ElasticEntity CreateFrom(Dictionary<string, object> members)
        {
            ElasticEntity entity = new ElasticEntity();
            entity.SetMembers(members);
            return entity;
        }

        public string GetValue(string property)
        {
            if (_members.ContainsKey(property))
            {
                object tmp= _members[property];
                if (tmp == null)
                    return string.Empty;
                else
                    return Convert.ToString(tmp);
            }
            return string.Empty;
        }

        public Dictionary<string, object> GetDictionary()
        {
            return _members;
        }

        internal void SetMembers(Dictionary<string, object> members)
        {
            this._members = members;
        }

        public void SetPropertyAndValue(string property, object value)
        {
            if (!_members.ContainsKey(property))
                _members.Add(property, value);
            else
                _members[property] = value;
        }
  
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            if (!_members.ContainsKey(binder.Name))
                _members.Add(binder.Name, value);
            else
                _members[binder.Name] = value;

            return true;
        }
  
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (_members.ContainsKey(binder.Name))
            {
                result = _members[binder.Name];
                return true;
            }
            else
            {
                return base.TryGetMember(binder, out result);
            }
        }
  
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            if (_members.ContainsKey(binder.Name)
                      && _members[binder.Name] is Delegate)
            {
                result = (_members[binder.Name] as Delegate).DynamicInvoke(args);
                return true;
            }
            else
            {
                return base.TryInvokeMember(binder, args, out result);
            }
        }

        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return _members.Keys;
        }
    }

 

Indexing

Our views will fetch the data and return as IDataReader. While indexing data, the index helper will iterate through the reader and from the reader the data get loaded to Dynamic ElasticEntity as shown below.

        private ElasticEntity GetRecordAsElasticEntity(IDataReader reader)
        {
            ElasticEntity entity = new ElasticEntity();
            for (int i = 0; i < reader.FieldCount; i++)
            {
                entity.SetPropertyAndValue(reader.GetName(i), reader.GetValue(i));
            }

            return entity;
        }

Before indexing the ElasticEntity, it will be serialized to json using the solution provided in Stackoverflow, it uses JavaScriptSerializer and is very fast. Same approach used while deserializing the json result from Elasticsearch while searching. For deserializing Elasticsearch result, I used json.net initially but deserializing is very slow compare to Javascript serializer.

Below is my Elasticsearch Indexer. It’s a very simple class that uses PlainElastic.Net.

    public class PlainElasticIndexer:Interfaces.IElasticIndexer
    {
        private ElasticConnection _connection;

        private string _indexName;
        private string _type;
        private string _defaultHost;
        private int _port;

        /// <summary>
        /// Default host to localhost and port to 9200. If the host and port is different
        /// then use the parameterized constructor and specify the details.
        /// </summary>
        private PlainElasticIndexer()
        {
            _connection = new ElasticConnection("localhost", 9200);
        }

        public PlainElasticIndexer(string host, int port, string indexName, string type)
        {
            this._defaultHost = host;
            this._port = port;
            _indexName = indexName;
            _type = type;
            _connection = new ElasticConnection(_defaultHost, _port);
        }

        /// <summary>
        /// Default host to localhost and port to 9200. If the host and port is different
        /// then use the parameterized constructor and specify the details.
        /// </summary>
        public PlainElasticIndexer(string indexName, string type):this()
        {
            _indexName = indexName;
            _type = type;
        }


        /// <summary>
        /// Add or update an index. If the ID exist then update the index with the provided json.
        /// </summary>
        /// <param name="json"></param>
        /// <param name="id"></param>
        public void Write(string json, string id)
        {
            string command = Commands.Index(_indexName, _type, id);
            string response = _connection.Put(command, json);
        }
    }

 

Search

Searching also uses a very simple class as shown below.

    public class PlainElasticSearcher:Interfaces.IElasticSearcher
    {
        ElasticConnection _connection;
        private string _indexName;
        private string _type;
        private string _defaultHost;
        private int _port;

        /// <summary>
        /// Default host to localhost and port to 9200. If the host and port is different
        /// then use the parameterized constructor and specify the details.
        /// </summary>
        private PlainElasticSearcher()
        {
            _connection = new ElasticConnection("localhost", 9200);
        }

        public PlainElasticSearcher(string host, int port, string indexName, string type)
        {
            this._defaultHost = host;
            this._port = port;
            _indexName = indexName;
            _type = type;
            _connection = new ElasticConnection(_defaultHost, _port);
        }

        /// <summary>
        /// Default host to localhost and port to 9200. If the host and port is different
        /// then use the other parameterized constructor and specify the details.
        /// </summary>
        public PlainElasticSearcher(string indexName, string type) : this()
        {
            _indexName = indexName;
            _type = type;
        }

        public string Search(string jsonQuery)
        {
            string command = new SearchCommand(_indexName, _type).WithParameter("search_type", "query_and_fetch")
                                    .WithParameter("size","100");
            string result = _connection.Post(command, jsonQuery);
            return result;
        }
    }

 

The Search function returns the result as plain json. The caller will convert the json to ElasticEntity using the function shown below.

        public static IList<ElasticEntity> ToElasticEntity(string json)
        {
            IList<ElasticEntity> results = new List<ElasticEntity>();
            JavaScriptSerializer jss = new JavaScriptSerializer();
            jss.RegisterConverters(new JavaScriptConverter[] { new DynamicJsonConverter() });

            JsonTextReader jsonReader = new JsonTextReader(new StringReader(json));

            var jObj = JObject.Parse(json); 
            foreach (var child in jObj["hits"]["hits"])
            {
                var tmp = child["_source"].ToString();
                dynamic dynamicDict = jss.Deserialize(tmp, typeof(object)) as dynamic;
                ElasticEntity elasticEntity = ElasticEntity.CreateFrom(dynamicDict);
                results.Add(elasticEntity);
            }

            return results;
        }

I added another class to convert the ElasticEntity to typed object. This helps the caller to convert the ElasticEntity to the Domain objects or to DTO.

    /// <summary>
    /// This class maps ElasticEntity to any DomainSpecific strongly typed class. Say for e.g.
    /// the requesting class wants the search result as a Customer class. This mapper will 
    /// create an instance of Customer and get the value from ElasticEntity and set 
    /// it to the Properties of Customer. One rule you should follow is
    /// the Columns in the index and Properties in the Domain class should match. 
    /// We can say it's a convention based mapping.
    /// </summary>
    public class EntityMapper
    {
        private string _pathToClientEntityAssembly;
        private Assembly _loadedAssembly = null;

        public EntityMapper(string pathToClientEntityAssembly)
        {
            _pathToClientEntityAssembly = pathToClientEntityAssembly;
        }

        internal T Map<T>(ElasticEntity entity) where T:class
        {
            T instance = this.GetInstance<T>();
            Type type = instance.GetType();
            PropertyInfo[] properties = type.GetProperties();

            foreach (PropertyInfo property in properties)
            {
                object value = entity.GetValue(property.Name);
                property.SetValue(instance, Convert.ChangeType(value, property.PropertyType), null);
            }
            return instance;
        }

        private T GetInstance<T>()
        {
            if(string.IsNullOrWhiteSpace(_pathToClientEntityAssembly))
                throw new NullReferenceException(string.Format("Unable to create {0}, path to the 
                                        assembley is not specified.", typeof(T).ToString()));

            if(_loadedAssembly==null)
                _loadedAssembly = Assembly.LoadFile(_pathToClientEntityAssembly);

            object instance = _loadedAssembly.CreateInstance(typeof(T).ToString());
            return (T)instance;
        }

    }

The client can call the search function as shown below.

var searcher = new SearchFacade(new PlainElasticSearcher(), assmPath);
IList<Customer> resultAsCustomer = searcher.Search("Customer", jsonQry).Results<Customer>();

 

where assmPath is the path to Assembly where Customer entity resides. If the user needs the result as ElasticEntity, then set the assmPath as null and make the call as shown below.

IList<ElasticEntity> searchResult = searcher.Search("Customer", jsonQry).Results();

 

Below code shows the implementation of SearchFacade.

    public class SearcherFacade
    {
        private IElasticSearcher _elasticSearcher;
        private string _pathToEntityAssembly;
        private IList<ElasticEntity> _searchResults;
        /// <summary>
        /// Use this constructor if the client will be dealing with dynamic ElasticEntity.
        /// </summary>
        /// <param name="elasticSearcher"></param>
        public SearcherFacade(IElasticSearcher elasticSearcher)
        {
            _elasticSearcher = elasticSearcher;
        }

        /// <summary>
        /// Use this constructor if the client wants to convert the ElasticEntity to domain specific class.
        /// </summary>
        /// <param name="elasticSearcher"></param>
        /// <param name="pathToEntityAssembly">path to Assembley to locate the Domain specific class</param>
        public SearcherFacade(IElasticSearcher elasticSearcher, string pathToEntityAssembly):this(elasticSearcher)
        {
            _pathToEntityAssembly = pathToEntityAssembly;
        }

        public SearcherFacade Search(string jsonQuery)
        {
            string jsonResult = _elasticSearcher.Search(jsonQuery);
            _searchResults=  DeserializeJson.ToElasticEntity(jsonResult);
            return this;
        }

        public IList<ElasticEntity> Results()
        {
            return _searchResults;
        }

        /// <summary>
        /// Converts dynamic ElasticEntity to strongly typed Domain Entity.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IList<T> Results<T>() where T:class
        {
            if (string.IsNullOrWhiteSpace(_pathToEntityAssembly))
                throw new NullReferenceException(string.Format("Please provide the Path and Assembly 
                          name in which class {0} resides. Set the fully qualified Assembly path 
                          via the constructor that take two parameters.", typeof(T).ToString()));

            EntityMapper mapper = new EntityMapper(_pathToEntityAssembly);
            IList<T> convertedResults = new List<T>();

            foreach (ElasticEntity entity in _searchResults)
            {
                T instance = mapper.Map<T>(entity);
                convertedResults.Add(instance);
            }
            return convertedResults;
        }
    }

 

This post gives a very simplistic and basic view of our ElasticSearch layer that I created. We have more functionality tailored for our needs. Hope this post helps some one to build a system using ElasticSearch.

 

Happy Coding…

Written by Sony Arouje

February 27, 2014 at 11:35 am

Lambda expression validation against Entity

leave a comment »

The system that I was building, I created a generic Record exist validator. What this does is check whether a specific record exist in the database. Say user can pass a Product code and check whether the Product exist in the database. In some scenario just checking a Product exist may not be sufficient, say while doing an invoice we should validate and raise error if a product is soft deleted but in some scenario we need to check whether the product exist nothing more. That means this custom status check should not implemented to the core Product exist validator. Developer should inject the custom Error condition logic based on the functionality he is working. This post explains the Custom Error conditions logic I implemented based on Lambda expression.

Lambda expression Validation

The easy way for a developer to write a Error condition using Lambda expression, pseudo code will be some thing like this.

(product=>product.isDeleted==true) then raise exception.

Initial 30 minutes I was thinking how to get the body of expression and validate the entity because we cannot directly apply Lambda expression to an entity like Product. When I go deeper into expression evaluation, I realize that I need more time than anticipated and might ended up with a complex functionality. This is what I did to solve this scenario.

  1. Add the entity to validate to a generic List
  2. Pass the lambda expression to Where() of the list.
  3. If the result count is greater than 0 raise the error.

see the code below.

public class ErrorCondition
{
    private object _criteria;
    private Exception _exceptionToRaise = null;

    public ErrorCondition IfTrue<T>(Func<T, bool> criteria) where T:class
    {
        _criteria = criteria;
        return this;
    }

    public void RaiseException(Exception exceptionToRaise)
    {
        this._exceptionToRaise = exceptionToRaise;
        return this;
    }

    internal void Validate<T>(T entity)
    {
        List<T> tmp = new List<T>();
        tmp.Add(entity);
        Func<T, bool> criteria = (Func<T, bool>)this._criteria;
        var result = tmp.Where<T>(criteria).ToList<T>();
        if (result.Count > 0)
        {
            if (_exceptionToRaise == null)
                throw new Exceptions.MaginusException("Error Condition is matching but 
                  no exception attached to ErrorCondition. Please set exception via 
                  RaiseException function.");
            throw _exceptionToRaise;
        }

    }
}

User can create a custom error condition as shown below.

ErrorCondition isDeletedCheckCondition = new ErrorCondition();
isDeletedCheckCondition.IfTrue<Product>(p => p.IsDeleted== true)
    .RaiseException(new Exception("Product is deleted"));

I created a class to group multiple error conditions user may need to add.

public class ErrorConditions
{
    IList<ErrorCondition> _errorConditions;
    public ErrorConditions()
    {
        _errorConditions = new List<ErrorCondition>();
    }

    public ErrorConditions Add(ErrorCondition condition)
    {
        this._errorConditions.Add(condition);
        return this;
    }

    internal void Validate<T>(T entity)
    {
        foreach (ErrorCondition errCondition in _errorConditions)
            errCondition.Validate<T>(entity);
    }
}

Now user can add multiple Error conditions as shown below.

ErrorConditions errorConditions = new ErrorConditions()
    .Add(new ErrorCondition().IfTrue<Product>(p => p.IsDeleted == true)
       .RaiseException(new Exception("Product is deleted and cannot be added")))
    .Add(new ErrorCondition().IfTrue<Product>(p => p.IsWithdrawn == true)
       .RaiseException(new Exception("Product is withdrawn.")));

Pass this errorConditions instance to Product Exist validator, Validator will call errorConditions.Validate<Product>(productToValidate) if the record exist in the database.

The key point to note here is, how we could evaluate an expression with the help of a List. Other wise I have to come up with complex code to analyze the body of the expression and things like that.

Happy coding…

Written by Sony Arouje

February 4, 2014 at 3:19 pm

Posted in .NET

Tagged with ,

Chromecast–My experience

leave a comment »

Recently I received a Chromecast, it’s a really great addition to my TV and can stream online videos and browse web very easily. Thanks to my brother in law for gifting me one.

Installation

Installing Chromecast is pretty simple, just connect the dongle to the HDMI slot and connect the power source to the TV’s USB slot. If your TV don’t have a USB slot then don’t worry it packed with an external power adapter and can connect to a power outlet.

When I first connected to my TV it is showing only a blank screen with some colored dots. Some google search revealed that it’s because of the Reset button. After doing some analysis of the dongle I realized that, when I insert the dongle to HDMI, the core is pushing backward and jamming the reset button. Thus the device enter into a reset state. If the same issue is happening to you then connect the device and try to pull the cover a little bit so that the reset button wont get stuck and you should be able to click the reset button.

Configuration

Next issue is installing the Chromecast app for my Android tab. I can’t install the app from Play store as I reside in India and the Chromecast is not released here yet. So I downloaded the apk from http://www.apkmaza.com/2013/07/chromecast-111.html and installed it. The setup was quite simple and the Chromecast Android app will guide you through each step. Once the setup is complete the dongle will check for the latest version and update it, if found. So make sure your WiFi router is connected to Internet.

If you don’t have any Android or iOS device then you can install a desktop app to configure the Chromecast dongle.

My Experience

Even though my TV is a smart one, means I can connect to my Wi-Fi. But browsing sites or watching YouTube is bit difficult with the aide of that remote control. With Chromecast I can browse any site in my computer and if required just cast it to my TV. That means my TV can show any Chrome tab from my computer, if it has photo, video or text. Even I can do multitasking when I am casting a tab to TV, that means my son can watch his favorite video from YouTube running in one of the chrome tab and casted to TV, mean while I can browse Facebook in another tab and is available only to my computer.

One thing I really missing in Chromecast is streaming the videos or music I stored locally in my computer. I am not sure why Google is not provided any option to stream local videos as it’s a very important feature for an awesome device like Chromecast. Hope in future Google will come up with a desktop app to stream local videos.

Not for you, If

  • you are looking to stream local videos.
  • you have no Wifi device.
  • your TV have no HDMI slot.

Written by Sony Arouje

November 18, 2013 at 6:02 pm

Posted in Review

Tagged with ,

KeyNotFoundException from NHibernate’s Session.Evict

leave a comment »

We started getting KeyNotFoundException when we evict an entity from session. The error is not consistent, some time it work and some time it wont. Searched a lot for the cause of this exception but not got any proper solution.

As per the stack trace, the error is because it couldn’t find the key in a collection. In a collection an entities identity is based on the hash code. In this case the entity has composite key. In the GetHashCode function, we append the values of composite properties and get the hash code of the resultant string.  When I start checking in more details I saw some properties we used in getting hash code is not exist as part composite key in the mapping file (some keys were removed from the composite mapping but not updated GetHasCode()). I need to do some more analysis to find why those extra fields screwing up the GetHashCode function. I will update the post later if I get the answer.

To avoid these kind of issues make sure to use only composite properties in the Equal and GetHashCode function and avoid using properties that are not part of composite.

 

Happy coding…

Written by Sony Arouje

November 13, 2013 at 6:12 pm

Follow

Get every new post delivered to your Inbox.

Join 149 other followers

%d bloggers like this: