Tuesday, November 20, 2012

ASP.NET ~ SQL Cache Notification issue

After enabling the database and table in sql server to support sql caching, I noticed that the cache is not still reflected with the updates. I verified to make sure if the database and tables are enabled and found that those are enabled. I opened the AspNet_SqlCacheTablesForChangeNotification table in sql server and noticed my table listed. The web.config file was also updated properly but still the cache was not getting invalidated. This was driving me crazy as why is the notification not working.

 

I enabled the database to support sql caching as follows:

C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727>aspnet_regsql -S <<server>> -E -d <<myDB>> –ed

 

I enabled the table to support sql caching as follows:

C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727>aspnet_regsql -S <<server>> -E -t <<myTable>> -d <<myDB>> –et

 

I have also set the web.config to support sql caching as follows:

 

    <caching>

      <sqlCacheDependency enabled="true" pollTime="2000">

        <databases>

          <add name="<<myDB>>" connectionStringName="myDBConnString" />

        </databases>

      </sqlCacheDependency>

    </caching>

 

After a while I checked the AspNet_SqlCacheTablesForChangeNotification table again just to make sure if everything is alright and that the table name is listed properly. I noticed that the case of the table name was different in AspNet_SqlCacheTablesForChangeNotification table. I was not sure but I just wanted to change case exactly as how it is displayed in the list of tables and give a try. I changed the table name manually in AspNet_SqlCacheTablesForChangeNotification table and then I tried again and it worked.

 

Whew….That was a great relief.

Hope this helps someone facing similar problem

Saturday, October 27, 2012

ASP.NET MVC ~ JSON decimal binding problem

With ASP.NET MVC, we will face problem when mapping JSON decimal values in an AJAX call to the model. For example consider the following class and the action method:

public class MyClass {
  
public decimal decValue1 { get; set; }
  
public int intValue1 { get; set; }
  
public decimal decValue2 { get; set; }
}

public ActionResult MyMethod(MyClass mc) {
  
return View();
}

and assume the following jquery ajax call:

$.ajax({
   type
: "POST",
   url
: "/Default/MyMethod",
   contentType
:'application/json',
   data
:JSON.stringify({decValue1:21.00,intValue1:3,decValue2:6.36})
});

On executing the above code, we will notice that the value for decValue1 will not be binded properly and that it will hold a value of 0. The reason is that the method JSON.stringify converts the value as follows before actually posting:

{"decValue1":21,"intValue1":3,"decValue2":6.36}

The default model binding behaviour believes the value of decValue1 to be of type integer (21) and therefore ignores to map this value to the destination type which is decimal. In order to overcome this problem, we will have to create our custom decimal binder and then register that in the application start event. The following is the code provided by Phil Haack to manage the custom binding of decimal types:

using System;
using System.Globalization;
using System.Web.Mvc;

public class DecimalModelBinder : IModelBinder
{
                  public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
                  {
                         ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
                         ModelState modelState = new ModelState { Value = valueResult };
                         object actualValue = null;

                         try
                        {
                                             actualValue = Convert.ToDecimal(valueResult.AttemptedValue, CultureInfo.CurrentCulture);
                         }
                        catch (FormatException e)
                        {
                                             modelState.Errors.Add(e);
                         }

                         bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
                         return actualValue;
                  }
}

and then we should register this custom decimal binder class in the application start event in the Global.asax.cs file as follows:

protected void Application_Start() 
{
    AreaRegistration.RegisterAllAreas();
    
    ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
 
    // All that other stuff you usually put in here...
}

Now, if we execute the same code, we should see the values mapped properly.

Thursday, October 25, 2012

Knockoutjs ~ Int16 data mapping fails from JSON to .NET

We design class comprising of different data types based on our requirement. Assume there is a requirement to store the age of a person. In this case, we can specify any numerical datatype for Age like byte, short or int. In most cases we end up choosing int (Int32) datatype. But sometimes developer opts for either byte datatype or short (Int16) datatype.

Let’s assume that we have the following Person class with Age datatype as short (Int16).

public class Person
    {
        public Int32 Id { get; set; }
        public string Name { get; set; }
        public Int16 Age { get; set; }
    }

The corresponding class definition on the cshtml view (javascript side) will be defined as follows:

function Person (person) {
        var self = this;
        self.Id=ko.observable(person.Id);
        self.Name=ko.observable(person.Name);
        self.Age=ko.observable(person.Age);
    }

The following would normally be our method to send the information back to the server:

        self.save = function (person) {               
            $.ajax({
                type: "POST",
                url: "Save",
                data: ko.toJSON(self),
                dataType: 'json',
                contentType: 'application/json;charset=UTF-8',
                success: function (result) {
                    alert("success");
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert("save error status: " + xhr.status);
                    alert("save error thrown: " + thrownError);
                }
            });
        };

And the following would be our ASP.NET code to capture the information:

        [HttpPost]
        public JsonResult Save(Person person)
        {
            if (person == null) throw new ArgumentNullException("person");

            var personBusiness = new PersonBusiness();

            var result = person.Id == 0 ? personBusiness.Insert(person) : personBusiness.Update(person);

            return Json(result);
        }

In the above case we would expect that the person object would have the information mapped properly provided by the user but unfortunately Age will hold value of 0 no matter what value is supplied by the user. It seems like the mapping of short datatype is not properly implemented. This becomes evident when we change the datatype of Age from Int16 to Int32. Now on the save action we can see that the Age attribute will has the value as set by the user.

Hope this solves someone facing such issue.

Thursday, October 18, 2012

"Dynamic" deep validation with KnockoutJS model

In this article, Knockout Model and Validating "inner" Models, we have seen how deep validation is done. Here is a snippet of that validation:
 
self.save = function () {
if (self.errors().length != 0) { //verifying the errors attribute using the count of errors
self.errors.showAllMessages(); //displaying the corresponding error messages
return; //returning the control providing user a chance to correct the issues
}
 
In the above method, we are simply invoking the showAllMessages method from the errors member. This will work for on occasion but sometimes this will fail and the validation error messages will not be displayed. In this situation, there is a workaround using which we can achieve this validation functionality working. The workaround is to add errors member to javascript class and then invoike the showAllMessage method for each of the instance of the class as shown below:
 
function Contact(id, phoneType, phone) {
var self = this;
self.ClientId = ko.observable(id);
self.PhoneType = ko.observable(phoneType).extend({ required: true });
self.Phone = ko.observable(phone).extend({ required: true });
self.errors = ko.validation.group(self); //adding the errors object for javascript class making each instance to hold the error individually
};
 
function ClientModel (id, firstName, lastName, email, contacts) {
var self = this;
self.Id = ko.observable(id);
self.FirstName = ko.observable(firstName).extend({ required: true, maxLength: 50 });
self.LastName = ko.observable(lastName).extend({ required: true, maxLength: 50 });
self.Email = ko.observable(email).extend({ maxLength: 50, email: true });
 
self.Contacts = ko.observableArray(ko.utils.arrayMap(contacts, function (aContact) { return aContact; }));
 }
 
Next we will update the save method as follows to perform the validation:
 
self.save = function () {
       var errorCount = 0;
ko.utils.arrayForEach(self.Contacts(), function(contact){
contact.errors.showAllMessages();
errorCount = errorCount + 1;
});
 
if (errorCount != 0) {
return;
       }
 
       //save code block
}
 
Hope this helps.

Wednesday, September 12, 2012

Dealing with JSON format date

When working with web application and dealing with JSON formatted data, we may come across date types that are represented as /Date(1347490800000)/. The value between the parenthesis i.e. 1347490800000 indicates the number of milliseconds elapsed since 1st Jan 1970.

In order to show the date in human understandable format, we will have to construct the date object using these millisecond values. In JavaScript, this can be done as follows:

var myJSONDate = "/Date(1347490800000)/"; //For demonstration purpose but in realtime we will get from Ajax call returning data in JSON format
var value = new Date(parseInt(myJSONDate.replace(/\/Date\((.*?)\)\//gi, "$1")));

In the above method, we have used native JavaScript’s regular expression technique to get hold of the millisecond value stripping the /, Date and parenthesis characters. In JavaScript, the new date object by default starts from 1st Jan 1970.

Similarly, we will can construct the DateTime object in .NET from JSON date as follows:

var jsonDate = "/Date(1347490800000)/";
jsonDate = System.Text.RegularExpressions.Regex.Replace(jsonDate, @"/Date\((.*?)\)\/", "$1");
var date = new DateTime(1970, 1, 1, 0, 0, 0, 0).AddMilliseconds(long.Parse(jsonDate));

Hope this helps…

Wednesday, September 05, 2012

Knockout Model and Validating "inner" Models

More and more technologies, projects and products are basing their foundation on MVC and MVVM principles. The reason is that it makes the project or product to be maintained easily without much headache. The latest trend in client based web development is also shifting towards MVVM model and the tool that is getting most widely used is the Knockout javascript library. It’s a great tool that eases binding making even the complex javascript tasks to be designed pretty easily like for example dynamically rendering design for multiple contacts and collecting details, etc..,

Basic Knockout Model Validation

Validating a basic knockout model is a straight forward task. We just have to use the extend method on the observable attributes and set the necessary parameters. Consider the following model:

function ClientModel (id, firstName, lastName, email) {
        var self = this;
        self.Id = ko.observable(id);
        self.FirstName = ko.observable(firstName).extend({ required: true, maxLength: 50 });
        self.LastName = ko.observable(lastName).extend({ required: true, maxLength: 50 });
        self.Email = ko.observable(email).extend({ maxLength: 50, email: true });

        self.save = function () {
            if (self.errors().length != 0) { //verifying the errors attribute using the count of errors
                self.errors.showAllMessages(); //displaying the corresponding error messages
                return; //returning the control providing user a chance to correct the issues
            }

            $.ajax({
                type: "POST",
                url: "Save",
                data: ko.toJSON(self),
                contentType: 'application/json',
                success: function (mydata) {
                    alert("Success");
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert("save method error status: " + xhr.status);
                    alert("save method error thrown: " + thrownError);
                }
            });
        };
};

$(document).ready(function () {
var clientModel = new ClientModel(1, "Hello", "World", "hell0@world.com");
clientModel.errors = ko.validation.group(clientModel); //setting up the errors attribute to the model to capture the validation error message
ko.applyBindings(clientModel);
});

The above is a basic model with validations added for the attributes using the extend method (More validation can be found here). The validation error messages are shown when the save method of the model is executed.

Deep Knockout Model Validation

Often we face situation where we will have a requirement for a complex model than the basic one. For example: our client may request us to design a solution to allow multiple contact numbers for a customer to be collected. In this case, the underlying model is changed as follows.

function Contact(id, phoneType, phone) {
        var self = this;
        self.ClientId = ko.observable(id);
        self.PhoneType = ko.observable(phoneType).extend({ required: true });
        self.Phone = ko.observable(phone).extend({ required: true });
};

function ClientModel (id, firstName, lastName, email, contacts) {
       var self = this;
       self.Id = ko.observable(id);
       self.FirstName = ko.observable(firstName).extend({ required: true, maxLength: 50 });
       self.LastName = ko.observable(lastName).extend({ required: true, maxLength: 50 });
       self.Email = ko.observable(email).extend({ maxLength: 50, email: true });

self.Contacts = ko.observableArray(ko.utils.arrayMap(contacts, function (aContact) { return aContact; }));

       self.save = function () {
            if (self.errors().length != 0) { //verifying the errors attribute using the count of errors
                self.errors.showAllMessages(); //displaying the corresponding error messages
                return; //returning the control providing user a chance to correct the issues
            }

            $.ajax({
                type: "POST",
                url: "Save",
                data: ko.toJSON(self),
                contentType: 'application/json',
                success: function (mydata) {
                    alert("Success");
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert("save method error status: " + xhr.status);
                    alert("save method error thrown: " + thrownError);
                }
            });
       };
};

$(document).ready(function () {
       var contacts = { new Contact(1, "Home", "1234567890"), new Contact(1, "Work", "9876543210") };
var clientModel = new ClientModel(1, "Hello", "World", "hell0@world.com", contacts);
clientModel.errors = ko.validation.group(clientModel); //setting up the errors attribute to the model to capture the validation error message
ko.applyBindings(clientModel);
});

The above is a also a model with validations added for the attributes using the extend method. The validation error messages excepts the contacts will be displayed when the save method of the model is executed. The reason is that we have not made the validation “deep” so the inner validations are not executed. In order to achieve this, we will have to include the following Knockout initialization block:

ko.validation.init({grouping: { deep: true }, messagesOnModified: false });

Adding the above line of code should make the inner validations work in most cases. But if it still doesn’t work, then we will have to add the errors attribute to the Contact model just like we have added for the ClientModel. The below listing shows the updated Contact model with errors attribute added:

function Contact(id, phoneType, phone) {
        var self = this;
        self.ClientId = ko.observable(id);
        self.PhoneType = ko.observable(phoneType).extend({ required: true });
        self.Phone = ko.observable(phone).extend({ required: true });

self.errors = ko.validation.group(self); //setting up the errors attribute to the Contact model to capture the validation error message
};

Having added the errors attribute to the Contact model, we also need to update the save method of the ClientModel to verify the errors collection attribute and return if in case there are errors. The updated save method is listed below:

self.save = function () {
       var errorExists = false;

if (self.Contacts().errors().length != 0) { //verifying the errors attribute from the Contact model
              self.Contacts().errors.showAllMessages(); //displaying the corresponding error messages
              errorExists = true; //set error flag to stop further processing
       }

if (self.errors().length != 0) { //verifying the errors attribute using the count of errors
              self.errors.showAllMessages(); //displaying the corresponding error messages
              errorExists = true; //set error flag to stop further processing
       }

if (errorExists) {
              return; //returning the control providing user a chance to correct the issues
       }

      
       $.ajax({
              type: "POST",
              url: "Save",
              data: ko.toJSON(self),
              contentType: 'application/json',
              success: function (mydata) {
                     alert("Success");
              },
              error: function (xhr, ajaxOptions, thrownError) {
                     alert("save method error status: " + xhr.status);
                    alert("save method error thrown: " + thrownError);
              }
            });
};

From the above updated save method, all the errors corresponding to the main model (ClientModel) and the child model (Contact) will be displayed.
Hope this helps!!!

Saturday, July 21, 2012

MVC ~ Transferring data from one page to another

Lot of times we would need to pass data from one page to another. The data could be a simple data or it can also be a complex data. In case of simple data, we can transfer using query string parameter and this does the job but when the size of the data is really big or if it is a complex type, then we need a different mechanism.

 

With MVC, we get the dictionary object to store the values at one end and retrieve it at the other end. These values are actually stored in session and lasts until the session terminates. Here is how we can make use of it:

 

//store the data to temp data dictionary. Data can be of any type

TempData[“myUniqueKey”] = value;

……

……

//retrieve the data from temp data dictionary.

if (TempData.ContainsKey(“myUniqueKey”))

myComplexData = TempData[“myUniqueKey”] as MyComplexData;

 

Happy Programming!!!

Sunday, July 15, 2012

Resolving HTTP Connection Timeout with Android applications

Response time of any application greatly matters especially those dealing with network operations. Sometimes the response from the server is reasonable but at times servers get busy and takes much time in responding. In such situation, we generally set timeout (in the range of 20-30 seconds) for method execution and handle the operation accordingly. This range of timeout is fair for web application but coming to mobile devices the response time has to be much quicker in the range of 3-5 seconds.

We define the connection timeout as follows:

HttpParams params = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 3000);

Here in the above snippet the connection timeout is set to 3000 milliseconds or 3 seconds. But executing the operation, we will notice that the execution does not return after 3 seconds though set rather it waits for a long time. In order to resolve this issue, along with setting the connection timeout, we also need to set the socket timeout as follows:

HttpParams params = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 3000);
HttpConnectionParams.setSoTimeout(params, 3000);

Now executing the operation, we will notice that the execution of code block returns in 3 seconds.

Hope this solves your problem…
Happy programming !!!

Thursday, July 12, 2012

Eclipse build error: The project was not built since its build path is incomplete. Cannot find the class file for xxxxx. Fix the build path then try building this project

We are creating a project in Eclipse studio, building the project and it executes. Everything goes fine and smooth. Next time we open the Eclipse studio and see red cross mark error beside our imports on basic java class references. To be more specific, we get the following issue:

The project was not built since its build path is incomplete. Cannot find the class file for xxxxx. Fix the build path then try building this project

Here xxxxx can be any of the java class file. We wonder why we get this and that it didn’t happen when we worked on the project just before Lunch!!! Annoying huh.. Ok so what is the problem and how to get rid of this ASAP? Well…the problem is with the reference of java library in our project. Sometimes Eclipse loses the reference path and require us to help it out. And how do we do that…here are the steps:

1.       Right click on the project from the Project Explorer and select “Properties”. Alternatively we can also select “Properties” from the Project menu.
2.       From the Properties dialog, select “Java Build Path” from the left side view.
3.       Clicking the “Libraries” tab we can see the libraries referenced in the project and will also see that something is wrong with JRE library referenced in the project as shown below:


4.       Next we select this library and remove it. Then we click the “Add Library…” button on the right and then select the “JRE System Library” and then click the “Next” button as shown below:


5.       By default, we will see that “Workspace default JRE” is selected as shown below. We can leave this as is and then click the “Finish” button


Now that we have the JRE library referenced to the project, we should see the error go away. But sometimes not. In this case, we do the regular clean-up of the project as follows:

1.       Project Menu -> Clean

2.       Right click on the project from “Project Explorer” and “Refresh”

3.       Right click on the project from “Project Explorer” and under "Android Tools" click “Fix Project Properties”

4.       May be even restart Eclipse if the above 3 steps doesn’t work and then repeat the 3 steps after restarting

Finally we see the error go away. Whew….
Hope this helps reduce your headache and…

Happy Programming!!!