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

Friday, 16 December 2011

Capturing network traffic between outlook client and exchange server (RPC over HTTP)

My previous article show how to capture network traffic between outlook client and exchange server with RPC over TCP. Now lets look at how to capture network traffic with RPC over HTTP.

1. Enable "Outlook Anywhere" on your Exchange server. Follow this link Enable Outlook Anywhere.

2. Now enable your outlook to use HTTP. Follow this link Setting Up Email (RPC over HTTPS).

Since all prep has now completed just follow the steps in my previous article Capturing network traffic between outlook client and exchange server (RPC over TCP).

I am sorry to say that there is too much point to the wisecrack that life is extinct on other planets because their scientists were more advanced than ours. ~John F. Kennedy

Capturing network traffic between outlook client and exchange server (RPC over TCP)

Analysing network traffic between outlook client and exchange server will help you decide network requirements connecting your datacenters to your users (ie.. using RPC over TCP). Wireshark is a simple tool that we are going to use to capture network traffic [ Download Wireshark ].

Information you should know before hand:

- IP address of client using Outlook (eg: 1.2.3.4)
- IP address of your exchange server (eg: 1.2.3.5)
- Outlook able to connect to your exchange server

Now here is the step-by-step guide.

1. Open wireshark

2. click on the interface (see screenshot above). Now you should see wireshark capturing network traffic. sample screenshot can be viewed here

3. Now start outlook

4. perform you routine tasks with outlook and let wireshark capture do the capture (leave this running for 30 mins)
5. Now stop capturing using the button


6. Save your capture


7. Now specify your filter "ip.src == 1.2.3.4 and ip.dst == 1.2.3.5" (use your exchange server IP address), this should display network traffic netween outlook client and exchange server. Filtered data gets displayed

8. Now select Statistics -> Summary. "Wireshark: Summary" dialog displays some very useful traffic information such as :-

- Between first and last packet (time taken in secs)
- Avg. packets/secs (average packets per sec)
- Avg. packets size (average packet size)
- Bytes (total amount of bytes transfered)
- Avg. bytes/sec (average bytes per sec)

Note that "Displayed" column is what you are interested as it shows data based on your filter. "Captured" columns will show everything.


. Any sufficiently advanced technology is indistinguishable from magic. ~Arthur C. Clarke

Tuesday, 13 December 2011

Using images in Microsoft’s Sharepoint Wiki

Today I was creating a wiki page for a project and want to show the design inside the wiki page. Ok that was not too difficult as wiki page editor provides an option to select an image. So I have tried using the link to image as "file://C:/Users/saif/Desktop/elapsedtime.png" but that did not work.
So I have created a picture library as per following steps :-

1. goto http://saif-teamserver/sites/DefaultCollection/default.aspx

2. goto "Site Actions" and select "Create"

3. select "Picture Library" as shown below


4. Give a name "SaifProjectPics" and select "create" should show your library


5. Now upload the image "elapsedtime.png"


6. clicking on the image should show the image in edit more, click on the image again so as to display as preview. The url should look like http://saif-teamserver/sites/DefaultCollection/SaifProjectPics/elapsedtime.jpg


That's it you can use this url in your wiki page. Try to add image in the wiki page and use the url as "http://saif-teamserver/sites/DefaultCollection/SaifProjectPics/elapsedtime.jpg" and your wiki page will have the image you needed.

The system of nature, of which man is a part, tends to be self-balancing, self-adjusting, self-cleansing. Not so with technology. ~E.F. Schumacher, Small is Beautiful, 1973

Wednesday, 7 December 2011

ASP.NET MVC using fileresult to export data in unicode

Exporting data to a file is a common feature websites provides to its customers. Now consider if the website is used by customers around the world, then this export data should support localization and globalization. Here is the snippet of code relating to WriteFile() for exporting data:-
protected override void WriteFile(HttpResponseBase response)
{
            response.Clear();
            response.ClearContent();
            response.ContentEncoding = System.Text.Encoding.Unicode;
            StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.Default);
            writer.WriteLine("Test Data");
            writer.Flush();
}
Since "response.ContentEncoding = System.Text.Encoding.Unicode;" is assigned to correct encoding browse should enforce writing data in unicode format but point to remember is streamwriter is initialised with encoding as "Encoding.Default". So browse ignores content encoding. Modify your code to have
StreamWriter writer = new StreamWriter(response.OutputStream, Encoding.Unicode);
Now this will enforce unicode format of the file. Also to verify if the file format is correct, rename the file to .bin and open Visual Studio to see the file in hex format. Verify the Byte Order Mark (BOM) of the file. First four char's "FF FE" confirms the file to be in unicode format. Refer to this article UTF-8, UTF-16, UTF-32 & BOM for more details about BOM.

Never trust anything that can think for itself if you can't see where it keeps its brain. ~J.K. Rowling

ASP.NET MVC not rendering correct dateformat using CultureInfo

Reading "DateTimeFormat" using cultureinfo is not getting clients date format with the following code :-
CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture(HttpContext.Current.Request.UserLanguages[0]);
DateTimeFormatInfo dtInfo = cultureInfo.DateTimeFormat;
After debugging the code, the dateformat is not honouring globalization ie.. if the client is in US but application is deployed in UK then the format is rendered correctly. So after looking into this article Globalization, Internationalization and Localization in ASP.NET MVC 3, JavaScript and jQuery Part 1 - by Scott HanselmanI have found that the issue is not with the code but a setting in web.config
globalization enableclientbasedculture="true" uiculture="auto" culture="auto"
Now this has solved the issue.

I am sorry to say that there is too much point to the wisecrack that life is extinct on other planets because their scientists were more advanced than ours. ~John F. Kennedy

Tuesday, 6 December 2011

Using session locking with EnableSession = true

Locking session object for each webservice is simple as just adding [WebMethod(EnableSession = true)] for each of the webmethods that require locking. At the same time if you also want to lock an object that is/will be part of the session object then Declare a static object
public static object lock_updatesharevalue = new object();
Now use this object in the webmethod to enable locking for an object in session
[WebMethod(EnableSession = true)]
public int UpdateShareValue(string Shareidentifier,float Sharevalue)
{
 lock(lock_updatesharevalue)
 {
    ///Update database with new share value
 }
 Session[Shareidentifier + "CurrentShareValue"] = Sharevalue;
}
So firstly session object is locked and then you are forcing a lock on a static object inside the webmethod that solves the issue of value failing to update when there are thousands of requests comming. Also point to note at this point is this method makes all the calls serialized and hence might reduce the performance and some of the calls might be waiting longer than expected so remember to increase the timeout in web.config
httpRuntime executionTimeout="10000" maxRequestLength="102400"
Refer to this article about Session State Overview

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

Monday, 5 December 2011

NHibernate : Arithmetic overflow error converting expression to data type int

As mentioned in SQL Server Error : Arithmetic overflow error converting expression to data type int article to use cast() in sql to correctly typecast for large numbers, Now this can be achieved using NHibernate & Fluent Hibernate as per the snippet below:-

 var criteria = session.CreateCriteria();
 criteria.SetProjection(Projections.ProjectionList()
 .Add(Projections.Count("ID").As("ID"))
 .Add(Projections.Sum(Projections.Cast(NHibernateUtil.Int64, Projections.Property("imagesize "))).As("TotalSize")))      
.SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean(typeof(ImagesSummary)));
ImagesSummary summary = (ImagesSummary)criteria.UniqueResult();

I regularly read Internet user groups filled with messages from people trying to solve software incompatibility problems that, in terms of complexity, make the U.S. Tax Code look like Dr. Seuss. ~Dave Barry

Friday, 2 December 2011

SQL Server Error : Arithmetic overflow error converting expression to data type int

After running a simple aggregate sql "select sum(imagesize) from images" is producing following error:-
Arithmetic overflow error converting expression to data type int
The table "images" is a very simple, having datatype of imagesize as bigint. The table has at least 2 million rows and should not be a problem at all. Tried number of options but no luck and finally found out the issue is actually because of the aggregate function it self. Aggregate function "sum" returns int but the totals of imagesize field is exceeding the size of int and hence was showing the error message. So the fix for this is changing the sql to return bigint as follows :-
select sum(cast(imagesize as bigint)) as 'TotalImageSize' from images
Now this worked.
Your most unhappy customers are your greatest source of learning. – Bill Gates

Monday, 28 November 2011

Apply JQueryUI for html element browse or input type=file

Jquery UI provides very best features that can be applied to html controls, one such feature is applying JQuery UI styling for buttons. Applying button style as such is very easy, but how can this be applied for a html element input(type=file). Now that looks little tricky. Ok first consider following html :



            


Now bind events
$(document).ready(function () {
        $('#btnBrowseAttachment').button();
        $('#btnBrowseAttachment2').button();

        $('#btnUpdateAttachment').button();

    });
So far we have added controls and have assigned JQuery UI buttons feature but we have too many controls. Apply following CSS styles
#btnBrowseAttachment2{
 position:absolute;
 /* start of transparency styles */
 opacity:0;
 -moz-opacity:0;
 filter:alpha(opacity:0);
 /* end of transparency styles */
 z-index:2; /* bring the real upload interactivity up front */
 width:270px;
}


Run the app and you should be able to see only one browse button (btnBrowseAttachment), ie.. btnBrowseAttachment2 button has been applied transparent style so that the click event binded to btnBrowseAttachment2 will fire when clicked btnBrowseAttachment.

For a list of all the ways technology has failed to improve the quality of life, please press three. ~Alice Kahn

Thursday, 20 October 2011

Generate summary using multiple aggregations with NHibernate

NHibernate allows adding multiple aggregations at the same time for a single ICriteria and generates multiple objects. Below sample shows how this can be achieved

using (var session = _sessionFactory.OpenSession())
            {
                ICriteria criteria = session.CreateCriteria(typeof(InvoiceLine));
                criteria.Add(Restrictions.Where(i => i.Invoice.ID == 1234));
                criteria.SetProjection(Projections.ProjectionList()
                    .Add(Projections.Count("ID"))
                    .Add(Projections.Sum("Price"))
                    .Add(Projections.Sum("Quantity"));
                object[] retObjects = (object[])criteria.UniqueResult();    
            }

Now you have got some list of objects which you can convert to your desired type. So you have to manually covert them, how about if NHibernate does this for you. First create a summary class which does not need to be part of you database
public class InvoiceSummary
    {
        public int LineCount;
        public long LineTotalPrice;
        public long TotalQuantity;        
    }
Now populate the data
      using (var session = _sessionFactory.OpenSession())
            {
                ICriteria criteria = session.CreateCriteria(typeof(InvoiceLine));
                criteria.Add(Restrictions.Where(i => i.Invoice.ID == 1234));
                criteria.SetProjection(Projections.ProjectionList()
                    .Add(Projections.Count("ID").As("LineCount"))
                    .Add(Projections.Sum("Price").As("LineTotalPrice"))
                    .Add(Projections.Sum("Quantity").As("TotalQuantity")));
     .SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean(typeof(InvoiceSummary)));
                InvoiceSummary summary = (InvoiceSummary)criteria.UniqueResult();
            }
NHibernate.Transform.Transformers.AliasToBean does the job of using the alias names to assign the properties of InvoiceSummary object Technological progress has merely provided us with more efficient means for going backwards. ~Aldous Huxley

Wednesday, 19 October 2011

Using NHibernate Criteria with Join to get row count

Google for lot of places for using Criteria object having joins and get rowcount either by using Projections.RowCount or CriteriaTransformer.TransformToRowCount. Now I have started looking into NHibernate source code which does also provides with examples of how to use it. So the example is as follows :-

  public void TransformToRowCountTest()
  {
   ISession s = OpenSession();
   ITransaction t = s.BeginTransaction();

   ICriteria crit = s.CreateCriteria(typeof(Student));
   ICriteria subCriterium = crit.CreateCriteria("PreferredCourse");
   subCriterium.Add(Property.ForName("CourseCode").Eq("MCSD"));


   ICriteria countCriteria = CriteriaTransformer.TransformToRowCount(crit);

   int rowCount = (int)countCriteria.UniqueResult();

   t.Rollback();
   s.Close();
  }
This does the job of counting number of students who are enrolled for a course with code "MCSD" 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

Wednesday, 12 October 2011

Add or Modify model data before submit in ASP.NET MVC when using jQuery Form Plugin

Having recently started using ASP.NET MVC for a website I am quite impressed the way MVC framework works as opposed to standard ASP.NET web forms.

Also coupled the website with jQuery Form Plugin which works seamlessly with ASP.NET MVC. jQuery Form Plugin basically provides various options such as
beforeSubmit - to validate before submitting data
success - to refresh/update content after success form submition

All works great, now what I actually need is to change data before submit so I have made some changes to jQuery Form Plugin as follows :-

.....
.....
// give pre-submit callback an opportunity to abort the submit
if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
    log('ajaxSubmit: submit aborted via beforeSubmit callback');
    return this;
}

// give addDataBeforeSubmit an opportunity to add custom data to be send along with form submit
if(options.addDataBeforeSubmit)
{
 var moreData = options.addDataBeforeSubmit();
 $.each( moreData, function( i, item ) {
  var bExists = false;
  $.each( a, function( j, aitem ) {
   if(aitem.name == item.key){
    aitem.value = item.value;
    bExists = true;
   }
  });
  if(!bExists)
  {
   a.push({ name: item.key, value: item.value });
  }
 });
}

// fire vetoable 'validate' event
this.trigger('form-submit-validate', [a, this, options, veto]);
if (veto.veto) {
 log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
 return this;
}

.....
.....


So this should cope with changing/adding new values to data that is to be sent for controller action (post)

Man is still the most extraordinary computer of all.
~John F. Kennedy

Friday, 16 September 2011

javascript or .js files not loading properly for static html file in chrome, firefox works fine in IE

Kind of feeling itchy since couple of weeks for not being able to find out why javascript or .js files not loading properly for static html file in chrome and firefox, but works absolutely fine in IE.

Ok now used browser debugging tools, IE show the .js files loaded successfully and works fine. But chrome/forefix shows script were loaded like gibberish (chineese,japanese something like that). Something fishy going on, but how would you find it. Ok tried some other static html files and works absolutely fine, but only the html generated using xsl is having the issue.

No luck, then suddenly felt something wrong with file. Ok opened the working file in notepad and have found this file is saved ASCII encoding. Now the buggy file its in unicode that's it.

IE loads all references in the format available by the file, but chrome/firefox tries to load based on the base file (.html file) which has

m eta http-equiv="Content-Type" content="text/html; charset=utf-16"

So modified xsl to output standard utf-8 format and job done.

Never trust anything that can think for itself if you can't see where it keeps its brain.
~J.K. Rowling

Tuesday, 13 September 2011

JQuery dialog inside update panel generating duplicate elements

JQuery dialog is a nice feature provided by JQuery UI, having said care should be taken when using dialog boxes inside an update panel.

Consider a dialog box is inside an update panel as shown below :-








Now javascript for displaying the dialog

var btnAddBloggerData= $("#btnAddBloggerData");
btnAddBloggerData
  .unbind("click")
  .bind("click", function () {
  this.disabled = true;
  $("#bloggerdata_dialogform").dialog("destroy");
  $("#bloggerdata_dialogform").dialog({
            autoOpen: true,
            modal: true,
            width: 500,
            buttons: {
                Cancel: function () {
                    $(this).dialog("close");
                },
                "Create": function (evt) {
                /*ajax call to update */
               }
            },
            close: function () {

            }
        });

});

All seems right and works fine. If this has been an asp.net server control (.ascx) would have completely weird behaviour. Each time a post back occurs a new dialog is added and finally there would be duplication of ids ie.. number of elements with id as "bloggerdata_dialogform" will increase for every postback.

Hence to resolve this issue do not use $("#bloggerdata_dialogform").dialog("destroy"); which is a killer. Now modify your script to

$.ready(function(){
   $("#bloggerdata_dialogform").dialog({
            autoOpen: false,
            modal: true,
            width: 500,
            buttons: {
                Cancel: function () {
                    $(this).dialog("close");
                },
                "Create": function (evt) {
                /*ajax call to update */
               }
            }
        });
});
var btnAddBloggerData= $("#btnAddBloggerData");
btnAddBloggerData
  .unbind("click")
  .bind("click", function () {
  this.disabled = true;
  $("#bloggerdata_dialogform").dialog("open");

});


So instead of destroying the element and use the same element for every postback.

Errors using inadequate data are much less than those using no data at all.
Charles Babbage

Monday, 12 September 2011

Visual studio 2010 run post build events based on debug or release mode

Using a batch file that should be run after post build is a common task. But some actions are not required in debug mode and some times in release mode.

To achieve this create 2 batch files
1. debugpostbuild.bat
2. releasepostbuild.bat

Update post-build event command line as follows:-
1. goto VS2010 -> right click on your project -> properties -> Build Events
2. copy below code

if $(ConfigurationName) == Release (
call $(SolutionDir)\debugpostbuild.bat
)
else (
call $(SolutionDir)\releasepostbuild.bat
)


That's it. so simple.

Any sufficiently advanced technology is indistinguishable from magic. ~Arthur C. Clarke

Thursday, 1 September 2011

Structure of jqGrid after generating html and its contents

Something which might be useful for everyone using jqgrid.

JQGrid HTML structure:




for short form refer to the following link stackoverflow.com.


Errors using inadequate data are much less than those using no data at all.
Charles Babbage

Wednesday, 24 August 2011

Formatting date in XSL using .NET standard formatting

Microsoft standard .NET date format can be used in xsl transform which is a key feature provided using msxsl:script Element.

The following snippet demonstrates using .NET "ToShortDateString" inside XSL transform:-


  
  

Above defined method "ToCSharpShortDateString" can be used as follows:-



Now that xsl is ready, lets use this with ASP.NET xml control . Code behind should look something like this.

XmlDocument doc = new Document(xmlPath);
 XPathNavigator nav = doc.CreateNavigator();
xmlData.XPathNavigator = nav;
string xslFileName = Server.MapPath("~/InvoiceReport.xsl");
xmlData.TransformSource = xslFileName;
xmlData.DataBind();


Technological progress has merely provided us with more efficient means for going backwards. ~Aldous Huxley

Thursday, 18 August 2011

jqGrid error at line $t.p.colModel[lvc].width += cr;

Recently I am getting an error in jqGrid plugin at the following line :-

$t.p.colModel[lvc].width += cr;


After debugging through the code this issue occurs with in the function
setGridWidth: function (nwidth, shrink)
.....
$t.p.colModel[lvc].width += cr;
.....

where nwidth is null

So while calling method setGridWidth on a grid make sure the width is a definite value and is greater than 0

Control is the wrong word. The practice is very much about sharing, and, in any creative practice, some individuals, whether partners or directors, are much closer to certain projects than I could ever be.
Norman Foster

Friday, 12 August 2011

Using SQL Server Compact with FluentNHibernate

FluentNHibernate is an alternative to NHibernate that supports Object Relational Mapping framework. Actually FluentNHibernate is build on top of NHibernate that provides strongly typed mapping using c# as opposed to xml mapping (.hbm.xml).

SQL Server CE (Compact edition) is commonly used for small applications as this would not need any packaging and is a simple file copy.

Using FluentNHibernate with SQL Server CE 3.5 file has a flaw in which any changes to mapping would not be reflected in the database unless the database is re-created.

Now this has been solved in the latest version of SQL Server CE 4.0, where in any changes are automatically reflected in the database.

Here is code to configure SQL Server CE
MsSqlCeConfiguration sqlconfig = MsSqlCeConfiguration.Standard.ConnectionString(ConnectionString);
FluentConfiguration fc = Fluently.Configure();
fc = fc.Database(sqlconfig );
ISessionFactory sessionFactory = fc.Cache(c => c
   .UseQueryCache()
   .ProviderClass())
   .Mappings(m => m
   .FluentMappings.AddFromAssemblyOf())
   .ExposeConfiguration((NHibernate.Cfg.Configuration config) => new SchemaUpdate(config)
   .Execute(false, true))
   .BuildSessionFactory();




Telegraphs are machines for conveying information over extensive lines with great rapidity.
Charles Babbage


JQGrid extension to track row selection between pages

Have been using JQGrid for quite some time now and was pretty impressed with the jqGrid plugin itself.

Ok now, how about extending jqGrid for tracking selection between pages. Here is a jquery extension that does the job.

; (function($) {
    $.jgrid.extend({
        enableTracking : true,
        gridTrackingIds : null,  
        TrackPageSelection: function (Rowids, selected, currentpageno) {
            var currentPage = this.GetCurrentPage(currentpageno);
            currentPage.RowIDs = new Array();
            if(selected)
            {
                currentPage.RowIDs = Rowids;
            }
            this.UpdateSelection(currentPage);
        }, 
        GetCurrentPage: function(currentpageno){
            var selectedPages = $(this).jqGrid.gridTrackingIds;

            var currentGrid = this;
            if (selectedPages == null) {
                selectedPages = new Array();
            }

            //find current page
            var currentPage = null;
            $.each(selectedPages, function (i, item) {
                if(item.Page == currentpageno){
                    currentPage = item;
                }
            });

            if(currentPage == null)
            {
                currentPage = {
                    Page : currentpageno,
                    RowIDs : new Array()
                };
                selectedPages.push(currentPage);
            }

            $(this).jqGrid.gridTrackingIds = selectedPages;
            return currentPage;
        },
        UpdateSelection: function(currentPage){
            var selectedPages = $(this).jqGrid.gridTrackingIds;

            var currentGrid = this;
            if (selectedPages == null) {
                selectedPages = new Array();
            }

            var filteredPages = $.grep(selectedPages, function(elem, index) { 
		            return elem.Page != currentPage.Page;
	            });

            selectedPages = filteredPages;
            selectedPages.push(currentPage);

            $(this).jqGrid.gridTrackingIds = selectedPages;

        },
        TrackSelection: function (id, selected, currentpageno) {
            var selectedItems = $(this).jqGrid.gridTrackingIds;            
            //find current page
           var currentPage = this.GetCurrentPage(currentpageno);

           if(selected){                
                var itemIndex = $.inArray(id, currentPage.RowIDs);
                if(itemIndex == -1){
		            currentPage.RowIDs.push(id);
	            }
            }
            else{
                var filteredItems = $.grep(currentPage.RowIDs, function(elem, index) { 
		            return elem !== id;
	            });
	            currentPage.RowIDs = filteredItems;
	        }
            this.UpdateSelection(currentPage);                            
        },
        UpdatePageSelection: function(currentpageno){            
            var selectedItems = $(this).jqGrid.gridTrackingIds;
            if(selectedPages != null)
            {
                //find current page
                var currentPage = this.GetCurrentPage(currentpageno);                
                if(currentPage != null)
                {
                    var selectedItems = currentPage.RowIDs;
                    var currentGrid = this;
                    if(selectedItems != null) {
                        $.each(currentGrid.jqGrid("getDataIDs"), function (i, id) {
                            if($.inArray(id, selectedItems) > -1) {
                                currentGrid.setSelection(id, false);
                            }
                        });                        
                    }
                }
            }
        }
        ResetTracking: function(){
            $(this).jqGrid.gridTrackingIds = null;            
        }
    });
})(jQuery);



All you need is to just copy this into a .js file and add it to your project. Now on row select just call this

onSelectRow: function(rowid,selected)
{
  var pageno = $(this).getGridParam('page');
  $(this).TrackSelection(rowid,selected,pageno);   
}




At each increase of knowledge, as well as on the contrivance of every new tool, human labour becomes abridged.
Charles Babbage

Tuesday, 9 August 2011

JQGrid sorting with date and time column using localization

Have been using JQGrid for quite some time now and have got stuck with unable to sort on DateTime columns. But finally managed a way to be able to handle this. Not only to allow sorting but also should be able use localization and display/sort in current local format.

Not use if this is the right way and works for me. The various DateTime formats available are listed at DateTime formats. Assuming the default date format is "The General Date Short Time ("g") Format Specifier".

DateTimeFormatInfo dateformatInfo = Thread.CurrentThread.CurrentCulture.DateTimeFormat;
string dateFormat = dateformatInfo.ShortDatePattern;

Now that we know the dateformat we are going to use is defined in a variable "dateFormat". Convert this date format string to JQGrid format.
public string ConverToJQGridDateFormat(string DateFormat)
{ 
            // Day
            DateFormat = DateFormat.Replace("dddd", "d");
            DateFormat = DateFormat.Replace("ddd", "d");
            DateFormat = DateFormat.Replace("dd", "d");
            // Month            
            DateFormat = DateFormat.Replace("MMMM", "M");
            DateFormat = DateFormat.Replace("MMM", "M");
            DateFormat = DateFormat.Replace("MM", "m");
            DateFormat = DateFormat.Replace("M", "m");
            // Year
            DateFormat = DateFormat.Replace("yyyy", "Y");
            DateFormat = DateFormat.Replace("yyy", "y");
            DateFormat = DateFormat.Replace("yy", "y");
            return DateFormat;
}


Ok now we have got our JQGrid date format, just apply this to colmodel options. Finally the column for "Invoice date" should be rendered as

name: 'InvDate',index: 'InvDate',sorttype:'date',formatter:'date',formatoptions:{srcformat:'d/m/Y',newformat:'d/m/Y'}
Another mode of accumulating power arises from lifting a weight and then allowing it to fall.
- Charles Babbage


Wednesday, 27 July 2011

ASP.NET MVC with SQL SERVER giving error "The SELECT permission was denied on the object 'account', database 'accounting', schema 'dbo'"

Developed an ASP.NET mvc application and ready to publish. Now steps anyone would have generally followed :-

1. Create an new application pool "AccountingAppPool" with ".NET Framework version" as v4.0.30319
2. Assign "Identity" as "NetworkService"
3. Publish the web application to http://localhost/Accounting/
4. Assign application pool as "AccountingAppPool"
5. Now check web.config

for connection string
   
    

.....


.....

6. using SQL server management studio connect to database. Add "NT AUTHORITY\NETWORK SERVICE" to logins to allow access for the identity of application pool

7. All done just run the application


Now a very disappointing error
"The SELECT permission was denied on the object 'account', database 'accounting', schema 'dbo'"

User is able to connect to database but does not have access. Ok now this is frustrating. Having spent hours thinking why this is not working.

Finally after a lot of help, found the issue is actually because of impersonation.

Now modified web.config to :-


Hurray! it worked.

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

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

Create Work Item Template for Team

Work item templates are very good option to apply a set of changes for a group of work items( for eg: bugs). But have you come across having difficulty not to be able to have shared work item templates, if so just follow these simple steps and you can achieve it.

Before creating a work item template, choose a shared location where each of team member have access such \\csharptechies\workitemtemplates, if you do not already have one create one shared folder on a network.

Now that you have the shared location, update your work item template settings in visual studio settings to point a shared location as follows :-

1. In the Tools menu, click Options.
2. In Options window, click Team Foundation Server Power Tools then click Work Item Template.
3. In the Work Item Template option page, click Browse to change the default location to \\csharptechies\workitemtemplates.
4. Click OK.

(above steps would only work for VS2010)

Now that your default location is set for work item template, create a new work item template.

After creating, browse to \\csharptechies\workitemtemplates and you should be able to see a new file created with extension .wt

Ask all of your team members to update there default work item template location.

Note:- A work item template is specific to a project

There is only one satisfying way to boot a computer. ~J.H. Goldfuss

Thursday, 7 April 2011

Stumbled upon decision to use either cross tab or pivot in SQL Server

Here is what it is..

Create a set of views which uses pivot using SQL Server 2008 express. All goes fine if the record count is in 1000's .... Testing with 20,000 found no issues what so ever with performance.

Now dealing with a million records, struggling with performance of 4 min's for simple query run.

Googling about this, have found a nice article

Cross Tabs and Pivots

As the article states using cross tab would give better performance than pivot, happy to accept that but this too was taking 2 to 3 min's.

So now changed the design, to remove pivot and an intermediate table to have the results.

I wish life had an Undo function. ~Author

Friday, 18 March 2011

Displaying JQGrid as defaulted with multiple search conditions

Just as you would apply default search condition for JQGrid its easy to apply multiple search conditions.

But this would need some more parameters, firstly enable multiple searches using the parameter "multipleSearch: true"

The code would as follows :-

$(function () {

 var GetFilters = function () {  
  var filters = null;  
  var filterData = { groupOp: "OR", rules: [] };
  filterData.rules.push({ field: "id", op: "eq", data: "1" });
  filterData.rules.push({ field: "id", op: "eq", data: "2" });
  filterData.rules.push({ field: "id", op: "eq", data: "3" });
  filterData.rules.push({ field: "id", op: "eq", data: "5" });
  filters = JSON.stringify(filterData)  
  return filters;
 }



 jQuery("#grid").jqGrid({    
  url:'GetDetails.asmx?team=All',    
  datatype: "json",    
  colNames:['ID','Name','Country','Progress'],    
  colModel:[    
  {name:'id',index:'id', width:55},    
  {name:'Icon',index:'Icon', width:90},    
  {name:'name',index:'name asc, invdate', width:100},    
  {name:'designation',index:'designation', width:80}],    
  rowNum:10,    
  rowList:[10,20,30],    
  pager: '#grid_pager',    
  sortname: 'id',    
  viewrecords: true,    
  sortorder: "desc",    
  caption:"JSON Data",
  serializeGridData: function (postData) {
   var filters = GetFilters();
   
  if(filters != null)
  {   
   postData.filters = filters;
  }
  else
  { 
   if (postData.searchField === undefined) postData.searchField = null;
   if (postData.searchString === undefined) postData.searchString = null;
   if (postData.searchOper === undefined) postData.searchOper = null; 
   if (postData.filters === undefined) postData.filters = null; 
  }
  return JSON.stringify(postData);
  },
 }).jqGrid('navGrid', '#grid_pager', { edit: false, add: false, del: false, search: true },
      {}, // edit options
      {}, // add options
      {}, //del options
      {multipleSearch: true }
 );
 

});

That's it multiple filters are passed as default search condition to jqgrid web service. Handling of this is not upto web service.

Web service would get the filters data as

"{\"groupOp\":\"OR\",\"rules\":[{\"field\":\"id\",\"op\":\"eq\",\"data\":\"1\"},{\"field\":\"id\",\"op\":\"eq\",\"data\":\"2\"},{\"field\":\"id\",\"op\":\"eq\",\"data\":\"3\"},{\"field\":\"id\",\"op\":\"eq\",\"data\":\"5\"}]}"

which if clearly formatted would be as

"{
 \"groupOp\":\"OR\",
 \"rules\":
  [
   {\"field\":\"id\",\"op\":\"eq\",\"data\":\"1\"},
   {\"field\":\"id\",\"op\":\"eq\",\"data\":\"2\"},
   {\"field\":\"id\",\"op\":\"eq\",\"data\":\"3\"},
   {\"field\":\"id\",\"op\":\"eq\",\"data\":\"5\"}
  ]
}"

This would need to be converted back from json to an object to actually read the data. The following snipped explains how to form a search condition :-

string sCond = string.Empty;
Dictionary(string, object) filtDat = (Dictionary(string,object))filters.FromJson();

string gpOp = (string)filtDat["groupOp"];
object[] ruleOp = (object[])filtDat["rules"];
for (int i = 0; i < ruleOp.Length; i++)
{
        Dictionary(string, object) filterData = (Dictionary(string,object))ruleOp[i];
 string field = (string)filterData["field"];
 string op = (string)filterData["op"];
 string data = (string)filterData["data"];
 sCond += GetCondition(field, op, data);
 if (i > 0)
 {
  sCond += " " + gpOp + " ";
 }
}

return sCond;


Your requirements may vary, just need to customise little to achieve your requirement.


Spreadsheet: a kind of program that lets you sit at your desk and ask all kinds of neat "what if?" questions and generate thousands of numbers instead of actually working. ~Dave Barry, Claw Your Way to the Top

Displaying JQGrid with default search condition

Being using JQGrid for sometime, have at one point required to display data in jqgrid but with a default search condition.

Its as simple as just passing data using the parameter serializeGridData in jqgrid

$(function () {

 var defaultsearchField = "id";
 var defaultsearchString = "5";
 var defaultsearchOper = "gt";



 jQuery("#grid").jqGrid({    
  url:'GetDetails.asmx?team=All',    
  datatype: "json",    
  colNames:['ID','Name','Country','Progress'],    
  colModel:[    
  {name:'id',index:'id', width:55},    
  {name:'Icon',index:'Icon', width:90},    
  {name:'name',index:'name asc, invdate', width:100},    
  {name:'designation',index:'designation', width:80}],    
  rowNum:10,    
  rowList:[10,20,30],    
  pager: '#pager',    
  sortname: 'id',    
  viewrecords: true,    
  sortorder: "desc",    
  caption:"JSON Data",
  serializeGridData: function (postData) {

  if(defaultsearchField != null)
  {
   postData.searchField = defaultsearchField; 
   postData.searchString = defaultsearchString; 
   postData.searchOper = defaultsearchOper;
  }
  else
  { 
   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);
  },
 });   

});

Now the webservice will get the default search condition and should be able to work straight away. Unless if search is not handled on web service side.

Three things are certain:
Death, taxes, and lost data.
Guess which has occurred.
~David Dixon, 1998, winning entry of the Haiku Error Messages 21st Challenge by Charlie Varon and Jim Rosenau, sponsored by Salon.com

Thursday, 10 March 2011

Using word wrap for text using css for words with out spaces

Many web pages contains some information which needs to be displayed using word wrap. consider a small example as below:-

Here is some content for the div element

CSS used in the above example will process the text with word wrap but only if it can find a space. If you would like to have a word warp for long words that does not have space then the CSS would be

Here is some content for the div element veryveryveryverylargewordwithoutspace


Three things are certain:
Death, taxes, and lost data.
Guess which has occurred.
~David Dixon, 1998, winning entry of the Haiku Error Messages 21st Challenge by Charlie Varon and Jim Rosenau, sponsored by Salon.com

Thursday, 10 February 2011

Generate client side script with custom control in ASP.NET

As you already know custom control gives the flexibility and allows to add complex features for a server control (refer to MSDN:Developing and Using a Custom Web Server Control).


Now consider you would like to display modal dialog using JQuery UI and the respective .js files are already loaded by the main website.The following snippet allows you to display a button from your custom control and generate a script block on the client side to handle the click event.

public class CustomWebControl : WebControl
{
 protected override void Render(HtmlTextWriter writer)
 {
         writer.Write(@"
          
          
              

Text to be displayed in the modal dialog.

"); this.Page.ClientScript.RegisterStartupScript(this.GetType(), "test-dialog-modal_1", @" "); } }

This is the simple case of explaining how to achieve it.


The most overlooked advantage to owning a computer is that if they foul up, there's no law against whacking them around a little. ~Eric Porterfield.

Wednesday, 5 January 2011

Passing vArguments or dialogArguments with window.open

Arguments can only be passed with window.showModalDialog which is quite helpful. But consider your application is using these arguments extensively in your website and suddenly it appears modal dialog is not supported on all browsers. Opera does not support modal dialog, now instead of changing the existing functionality the work around would be as follows:-

1. Detect if browser support modal dialog or not and then assign arguments
var vArguments = new Object();
vArguments.test1 = "test1 data";
vArguments.test2 = "test2 data";
if (window.showModalDialog) {
window.showModalDialog(sURL, vArguments, sFeatures);
}
else
{
window.dialogArguments = vArguments;
window.open(sURL, "_blank", sFeatures);
}

2. Now inside the pop-up window access the arguments

 var dialogArguments ;
if (window.showModalDialog) {
 dialogArguments = window.dialogArguments;
}
else {
 dialogArguments = window.opener.dialogArguments;
}
alert(dialogArguments.test1);
alert(dialogArguments.test2);

Now this should work like a charm.


Man is still the most extraordinary computer of all. ~John F. Kennedy
Copyright © 2013 Template Doctor . Designed by Malith Madushanka - Cool Blogger Tutorials | Code by CBT | Images by by HQ Wallpapers