Blogger Widgets
  • Sharing Photos using SignalR
  • TFS Extenstion - allows copy work items between projects
  • Displaying jquery progressbar with ajax call on a modal dialog
  • Managing windows services of a server via a website
  • Exploring technologies available to date. TechCipher is one place that any professional would like to visit, either to get an overview or to have better understanding.

Search This Blog

Thursday, 23 June 2011

Using jQuery tabs with ASP.NET MVC

Developing websites using ASP.NET webforms does have its benefits. Now why not give a try with ASP.NET MVC. Ok Here is a simple article that describes about using jquery tabs for MVC application.

As everyone know ASP.NET MVC template provides menu options for various actions, now why not provide the same options with jquery tabs. Here is how it compares both

Standard MVC template


MVC template with jquery tabs


Now let look into details of how this can be achieved. First add the required references for jquery scripts as follows inside head tag of site.master





As with ASP.NET MVC what we need is
- Model
- View
- Controller

Let's first start with creating the required model data required for our JQuery tabs. Here is what we need to achive:-

1) Model for storing data for a tab panel
2) Model for maintaining list of tab panels (ie.. tabs)

Remember to create these classes under Models folder.

1) Model for storing data for a tab panel
Create JQueryTabPanel data model for tab related information and its relevant controller action as follows:-

JQueryTabPanel.cs
namespace MvcApplication.Models
{
    public class JQueryTabPanel
    {
        public string TabPanelID { get; set; }
        public string TabPanelTitle { get; set; }
        public string TabPanelAction { get; set; }
        public string TabPanelController { get; set; }

        public JQueryTabPanel(string PanelID, string PanelTitle, string PanelAction, string ControllerName)
        {
            this.TabPanelID = PanelID;
            this.TabPanelTitle = PanelTitle;
            this.TabPanelAction = PanelAction;
            this.TabPanelController = ControllerName;
        }
    }
}

2) Model for maintaining list of tab panels (ie.. tabs)
Create JQueryTabs data model for tab related information and its relevant controller action as follows:-

JQueryTabs.cs
namespace MvcApplication.Models
{
    public class JQueryTabs
    {
        public List JQueryTabPanels { get; set; }

        public JQueryTabs()
        {
            JQueryTabPanels = new List();
        }
    }
}

So far we have created the required data model, now let move on to creating the respective views. Create the following view under Shared folder ( as it will be common for the entire web application).

JQueryTabsControl.ascx

Finally lets update the controller. As these tabs are common for all controllers lets create a base controller as follows :-

BaseController.cs
namespace MvcApplication
{
    public class BaseController : Controller
    {

        public BaseController()
        {
            JQueryTabs tabs = new JQueryTabs();
            tabs.JQueryTabPanels.Add(new JQueryTabPanel("1", "Home", "Index", "Home"));
            tabs.JQueryTabPanels.Add(new JQueryTabPanel("2", "About", "About", "Home"));

            ViewData["JQueryTabs"] = tabs;
        }

    }
}

Now modidy site.master so as to render the JQueryTabsControl.

site.master

Also add jquery script to populate the tabs and select the respective tab based on the controller action.

common.js


That's it now you should have a working model of ASP.NET MVC using jquery tabs.


The real danger is not that computers will begin to think like men, but that men will begin to think like computers. ~Sydney J. Harris

Friday, 17 June 2011

Google charts in xsl

Google charts is a simple and easy way to provide charts on a webpage. Refer to
Google Charts for more info.

A simple chart can be produced using img tag





Using the same in xsl will not work as the charactors ?,& etc will not be recognized as you would expect. Hence you should give this as

src="https://chart.googleapis.com/chart?chs=250x100&chd=t:60,40&cht=p3&chl=Hello|World" 

Any refernce to url can be applied in similar fashion.

The real danger is not that computers will begin to think like men, but that men will begin to think like computers. ~Sydney J. Harris

Disable a button after onclick inside an update panel

Avoiding users to click on a button more than once can be done as follows :-

btnSubmit.Attributes.Add("onclick", "this.disabled=true;" + Page.ClientScript.GetPostBackEventReference(btnSubmit, "").ToString());

This method is quite nice but if you would want to apply for entire website then you would have to duplicate the code in every page, usercontrols etc. Instead this simple script allows you to handle once for all

 var prm = Sys.WebForms.PageRequestManager.getInstance();
    prm.add_initializeRequest(InitRequest);
    prm.add_endRequest(EndRequest);
    function InitRequest(sender, args) {
        var btn = $get(args._postBackElement.id);
        if (btn && btn.type == "submit") {
                btn.disabled = true;
        }
    }
    function EndRequest(sender, args) {      
        var btn = $get(sender._postBackSettings.sourceElement.id);
        if (btn && btn.type == "submit") {
                btn.disabled = false;
        }
    }

Above mentioned method is for ASP.NET ajax where update panels are used.

Hardware: the parts of a computer that can be kicked. ~Jeff Pesis

Friday, 20 May 2011

Finding the count of entities using using ObjectContext in Entity Data Model

The best part of using Entity Data Model designer is having the facility to use LINQ with the objectcontext.

Now consider you have the object-layer code created as follows-
/// 
/// No Metadata Documentation available.
/// 
public partial class InventoryEntities : ObjectContext
{

//autogenerated code
 /// 
        /// No Metadata Documentation available.
        /// 
        public ObjectSet Products
        {
            get
            {
                if ((_Products == null))
                {
                    _Products = base.CreateObjectSet("Products");
                }
                return _Products ;
            }
        }
        private ObjectSet _Products; 

}

To find the list of products in the database the code should be

InventoryEntities inventory = new InventoryEntities ();
long cnt = inventory.Products.Execute(MergeOption.AppendOnly).LongCount();


The inside of a computer is as dumb as hell but it goes like mad!
~Richard Feynman

Object-Layer Code not getting updated correctly

Generating Object-Layer Code is the easiest way to generate code for database instead of writing the for yourself. refer to Generating Object-Layer Code

Code can be generated for Object-Layer as follows:-

1. Create an Entity Data Model design
2. Right click on EDM design and select "Update Model from Database..."
3. Select the database and select the required table
4. Select finish to get the code generated

The code is now generated and is ready to be used.

Now consider you have modified the database tables and would like to update Object-Layer code. Just need to run the steps from 2 to 4.

But you might have observed that the code does not get updated, the reason being the code is generated only first time it is created.


This is a feature which is provided so that customised changes to the code does not get lost when re-generating the code.


So to overcome this create another class that extends this class and add all your custom code to the derived class.

Every time you update the database
- Remove the contents of the file TestDatabase.Designer.cs.
- Re-run the steps from 2 to 4, this will recreated the code that reflects the database changes



To have no errors
Would be life without meaning
No struggle, no joy
~Brian M. Porter, 1998

Wednesday, 4 May 2011

Improving Performance of JQGrid for millions of records : Part2


This article will address more from ASP.NET point of view assuming you have already read Part 1


Now that you have all the back-end available lets get on with developing the website.

Start with the usual steps

1. Create an ASP.NET website
2. Add the required java scripts (JQuery, JQueryUI, JQGrid plugin)
3. Now add a new web service to the project and name it InvoicingService

InvoicingService.cs should look like
[WebMethod, ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string GetInvoiceData(int? page, int? rows, string sidx, string sord, bool _search, string searchField, string searchOper, string searchString)
{
// code to run stored procedure and get the relavent data from database 
// need to pass the search condition, page and rows to stored procedure
}

refer to call a stored procedure .

Now modify default.aspx to have the following :-

Create a new script file common.js with following code

$(function () {

  $("#grid_invoices_tbl").jqGrid({
        url: "InvoicingService.asmx/GetInvoiceData",
        datatype: "json",
        mtype: 'POST',
        ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
        colNames:
            ['INVOICEID',
            'CUSTOMER NAME',
            'PRODUCT NAME',
            'UNIT PRICE',
            'QUANTITY',
            'TOTAL PRICE'],
        colModel: [
        { name: 'INVOICEID', index: 'INVOICEID', align: 'left'},
  { name: 'CUSTOMERNAME', index: 'CUSTOMERNAME', align: 'left'},
  { name: 'PRODUCTNAME', index: 'PRODUCTNAME', align: 'left'},
  { name: 'UNITPRICE', index: 'UNITPRICE', align: 'left'},
  { name: 'QUANTITY', index: 'QUANTITY', align: 'left'},
  { name: 'TOTALPRICE', index: 'TOTALPRICE', align: 'left'}
  ],
        rowNum: 10,
        rowList: [5, 10, 20, 50],
        pager: '#grid_invoices_pager',
        sortname: 'INVOICEID',
        viewrecords: true,
        sortorder: "asc",
        caption: 'Invoice Details',
        serializeGridData: function (postData) {
            if (postData.searchField === undefined) postData.searchField = null;
            if (postData.searchString === undefined) postData.searchString = null;
            if (postData.searchOper === undefined) postData.searchOper = null;            
            return JSON.stringify(postData);
        },
        loadError: function (xhr, status, error) {
            alert(status);
            alert(xhr);
            alert(error);
        },
        loadComplete: function (data) {
           // alert(data);
        },
        jsonReader: {
            root: function (obj) { return obj.d.rows; },
            page: function (obj) { return obj.d.page; },
            total: function (obj) { return obj.d.total; },
            records: function (obj) { return obj.d.records; }
        },             
        autowidth: true
    }).jqGrid('navGrid', '#grid_invoices_pager', { edit: false, add: false, del: false, search: true });

});


Hope this should have helped you to handle huge amounts of data.


Computers make it easier to do a lot of things, but most of the things they make it easier to do don't need to be done.
~Andy Rooney

Improving Performance of JQGrid for millions of records : Part 1

JQGrid plugin does not require any introduction for itself. As everyone already knows the fact that JQGrid plugin is a powerful plugin for serving data from server to the client. Also it provides very good features such as sorting, paging, filtering etc.

Now lets look at how JQGrid can be used in ASP.NET for serving millions of records with out having the following effects:-

- website hanging
- memory leaks
- page time out
- taking 5 to 6 mins to serve data (only after increasing page timeout)
-
etc.

Well if you have come before you have decided on the implementation this is the right article for you.

But if you have come here after facing the issue then the changes you would have to make will be little painful but will solve your nightmares once for all.

Now enough of the explanation lets start with step by step guidelines.

This article will address more from database point of view.

Assume a simple database with 2 tables (Customer and Invoice) as follows:-

CREATE TABLE [dbo].[CUSTOMER](
   [CUSTOMERID] [bigint] IDENTITY(1,1) NOT NULL,   
   [CUSTOMERNAME] [nvarchar](255) NULL,
   [ADDRESS] [nvarchar](255) NULL
);

CREATE TABLE [dbo].[PRODUCT](
   [PRODUCTID] [bigint] IDENTITY(1,1) NOT NULL,   
   [PRODUCTNAME] [nvarchar](255) NULL,   
   [UNITPRICE] [int] NULL
);

CREATE UNIQUE NONCLUSTERED INDEX [CUSTOMER_CUSTOMERID_IDX] ON [dbo].[CUSTOMER] ([CUSTOMERID] ASC);

CREATE TABLE [dbo].[INVOICE](
   [INVOICEID] [bigint] IDENTITY(1,1) NOT NULL,      
   [CUSTOMERID] [bigint] NOT NULL,      
   [PRODUCTID] [int] NULL,
   [QUANTITY] [int] NULL
  );

CREATE UNIQUE NONCLUSTERED INDEX [INVOICE_INVOICEID_IDX] ON [dbo].[INVOICE] ([INVOICEID] ASC);
CREATE NONCLUSTERED INDEX [INVOICE_CUSTOMERID_IDX] ON [dbo].[INVOICE] ([CUSTOMERID] ASC);

Now create a view to get the data from both the tables

CREATE VIEW [dbo].[INVOICE_VIEW]  
AS  
SELECT   
 INV.[INVOICEID],  
 CUS.[CUSTOMERNAME],  
 PRD.[PRODUCTNAME],  
 PRD.[UNITPRICE],   
 INV.[QUANTITY],  
 (PRD.[UNITPRICE] * INV.[QUANTITY]) AS [TOTALPRICE]   
FROM   
 INVOICE INV,  
 CUSTOMER CUS,  
 PRODUCT PRD  
WHERE  
 INV.CUSTOMERID = CUS.CUSTOMERID AND  
 INV.PRODUCTID = PRD.PRODUCTID  

Now crucial part is to get the data from the server and the data you need to display in a page (either 10,20 etc based on the page size).

Now lets create a stored procedure to serve the data required for jqgrid.
CREATE PROCEDURE [dbo].[GETINVOICES]
 @CONDITION nvarchar(255) = NULL,
 @SORTCONDITION nvarchar(255) = NULL,
 @PAGE INT,
 @ROWS INT,
 @RECORDCOUNT INT OUTPUT
 AS 
 DECLARE
  @params nvarchar(4000),
  @sql    nvarchar(4000),
  @STARTRECORD INT,
  @ENDRECORD INT
 BEGIN

  -- SET NOCOUNT ON added to prevent extra result sets from
  -- interfering with SELECT statements.
  SET NOCOUNT ON;

  SET @RecordCount = 0;

  SET @SQL = 'SELECT @cnt = COUNT(*) FROM [INVOICE_VIEW] WHERE ' + COALESCE(@CONDITION,' 1 = 1');
  SELECT @params = N'@cnt int OUTPUT';
  EXEC sp_executesql @sql, @params, @cnt = @RecordCount OUTPUT
  
  if(@RecordCount > 0)
  begin
  
   SET @ENDRECORD = @PAGE * @ROWS;
   SET @STARTRECORD = @ENDRECORD - @ROWS + 1;      
   
   SET @SQL = 'select INVOICE_VIEW.INVOICEID,CUSTOMERNAME,PRODUCTNAME,UNITPRICE,QUANTITY,TOTALPRICE from [INVOICE_VIEW],'; 
   SET @SQL = @SQL  + '(select row_number() over (' + COALESCE(@SORTCONDITION,' order by INVOICEID asc ') + ') as rowid,INVOICEID';   
   SET @SQL = @SQL  + ' from [INVOICE_VIEW]) INVOICEROWS';
   SET @SQL = @SQL  + ' where ' + COALESCE(@CONDITION,' 1 = 1');
   SET @SQL = @SQL  + ' and (INVOICEROWS.rowid between @PARAM_STARTRECORD and @PARAM_ENDRECORD)';
   SET @SQL = @SQL  + ' and INVOICE_VIEW.INVOICEID = INVOICEROWS.INVOICEID';
   
   SELECT @params = N'@PARAM_STARTRECORD int,
       @PARAM_ENDRECORD int';

   EXEC sp_executesql @SQL,@params,@PARAM_STARTRECORD=@STARTRECORD,@PARAM_ENDRECORD=@ENDRECORD
  end;

 END;

continue to Improving Performance of JQGrid for millions of records : Part2

Database: the information you lose when your memory crashes.
~Dave Barry, Claw Your Way to the Top
Copyright © 2013 Template Doctor . Designed by Malith Madushanka - Cool Blogger Tutorials | Code by CBT | Images by by HQ Wallpapers