Find out if you are runing on a 64-bit Precessor

Goal:

FInd out if you are runing on a 64-bit Processor

Answer:

Go to the command prompt (type cmd int the Start -> Search box)

type the follownig command: set | find "PRECESSOR_ARCHITECTURE"

If you get ADM64 back (or something similar with 64 in it) you are running on a 64-bit processor, so you would be able to run  Windows 7's 64 bit OS. If you get something like x86 you are running on the older 32-bit architecture and will not be able to run a 64-bit OS.

Restructuring a large ASP.Net Mvc app

So the issue is, you have a very large ASP.Net MVC app with many controllers and actions and don't know (or do) on how to restructure it for better maintenance.

This article contains some thoughts around what my experiences were with building a large scale app with 10K+ lines of jQuery and 266 Actions dispersed over 98 Controllers.

In the beginning:

Yes God created .... no I created a relatively small scale Mvc app based on a very limited set of requirements, more like a XP or Agile experience or learn as you go. The user community did not know what they wanted and the prototype was based on a missed conception of what the business' core day-to-day focus was (of course we did not know this at the time). There were only a few controllers and they were small.

Then we discovered the jQuery Grid by Tony Tomov (awesome free plug-in) which supports a ton of ajax features, so we decided to use it for all of our lists and also for a lot of CRUD functions. This very quickly expanded the controllers to a very large size. At this time I decided to not split the controllers as it might introduce bugs. For example an Account has a New, Update, Delete, Create and Edit action, and now it has a List and CUD action (2 actions) added for each grid. Since the Account page has 9 tabs with 13 grids it now has an added 26 actions on that single AccountController controller and then some for other ajax type functions.

So then very quickly, as the customers saw the app, new requirements were added and the controllers grew even bigger.

The decision then came as to what to do and how to refactor the code. I ran this past a colleague of mine to find out what he thinks: Large controller with all the logically related actions together (yes all 39 actions at some point) or to split them into smaller but many different controllers? It seemed that keeping it all in one controller was a good decision since when you need to fix something on the account page with all the tabs with grids on them you know you need to go to the AccountController controller, right!? However, what if the requirements change and these grids need to be also displayed in other places, that's right, like on the Contact's maintenance page that has the same tabs as the Account page (only filtered by the contact for that account). Now I have a duplicate set of actions that perform essentially an identical function to those on the Account's controller. That is when it became clear that the controllers' actions should not be arranged according to how the screens look like but to adhere to the SRP.

Lets look at an example. The Account has a list of Calls, Contacts, Contracts and Lessons Learned. Even though these are tabs on the account's page, they need to be self contained. So this is how they were disseminated and re-arranged to adhere to SRP:

AccountController: New, Create, Edit, Update, Delete, List actions

CallController: New, Create, Edit, Update, Delete, List actions

ContactController: New, Create, Edit, Update, Delete, List actions

ContractController: New, Create, Edit, Update, Delete, List actions

LLController: New, Create, Edit, Update, Delete, List actions

The AccountController had a very large constructor since we used IoC Castle Windsor to inject the Repository (DAO type functions) into the constructor; to support all the DAO functions for calls, contacts, contracts and lessons learned. Now the constructor of each controller is very small and only cares about the Repositories it needs. In addition, to mention one example, the Calls tab on the account and contact screens now share the same action defined on another controller specifically to support the jqGrid functions for calls, the CallGridController with its 2 (yes only 2) actions ListCallsForjqGrid() and SaveCallForjqGrid(), rather than duplicating it. Now another developer knows that no matter where the jqGrid is displayed for calls, they can always find it on the CallGridController.

These are just some of the benefits of creating smaller controllers. Feel free to comment and share your ideas and experiences.

How to set the windows path in Windows 7

 

How to set the path in Windows 7.

Goal:

Setting the windows command path in Windows 7

Additional information:

Modifying the path statement will enable an MS-DOS window opened in Microsoft Windows as well as older programs to locate files that may be required to run the program.

In the old MS-DOS environment we used the PATH= command, located in the autoexec.bat file. Additional information about the MS-DOS path command that is still usable in Windows 2000 and Windows XP can be found on our path command page, additional information about the MS-DOS command can be found on our set command page.

See our dictionary path definition for additional information about this term and related definitions.

Answer:

The path is now managed by Windows 7 and not the autoexec.bat or autoexec.nt files. To change the system environment variables, follow the below steps.

  1. From the desktop, right-click My Computer and click Properties.
  2. In the System Properties window, click on the Advanced tab.
  3. In the Advanced section, click the Environment Variables button.
  4. Finally, in the Environment Variables window (as shown below), highlight the Path variable in the Systems Variable section and click the Edit button. Add or modify the path lines with the paths you wish the computer to access. Each different directory is separated with a semicolon as shown below.

    C:\Program Files;C:\Winnt;C:\Winnt\System32

Windows enviromental path settings

Do I have a 32-bit or 64-bit processor?

How to check what kind of processor you have (CPU) and what operating system can I run on it?

An X64 has a 64 bit microprocessor, whereas an X86, derived from the old 8086 PC, has a 32 bit microprocessor. A 32 bit machine and/or OS (operating system) is limited to about 3.55GB of memory, and an X64 is limited to about 17,179,869,184 gigabytes, 17,179,869 terabytes, or about 16 exabytes of RAM. Also a 32-bit CPU cannot run an 64-bit OS.

So, how to check your CPU:

Since you cannot run WIndows7-64x on a 32-bit machine lets look at windows 7.  From the Start icon on the toolbar select Control Panel. Look for Hardware and SOund and select View devices and printers. Double-click your computer (will be labeled with your machine name). A Properties window pops-up with two tabs, select the Hardware tab. Look for a name starting with ACPI, with Type of Computer. If it says ACPI x64-based PC you know you have a 64-bit machine, CONGRATULATIONS! You can now install a 64-bit OS like Vista-64 or Windows7-64 and run any of your old software as the new 64-bit OS "knows" (is compatible) how to run the 32-bit apps.

What about memory?

If you want to install more than 4GB or RAM you will need to have a 64-bit CPU and also run a 64-bit OS otherwise you are wasting your money.

How to stop and prompt user when closing browser

Scenario:

For some reason you want to stop the user from closing the browser window or from redirecting away from the current page, based on some condition.


The solution:

window.onbeforeunload = function(event) {
            return true;
        }

This will prompt you for input (like the JavaScript confirm pop-up menu). There is no way to override the text though.

Some concerns:
This works great but it may not be what you want all the time, as no matter if you click a hyperlink, hit submit, etc will prompt the user, which. So here is an example where when any input value on the screen has changed, I want to prompt the user only then and also only if the user decides to redirect from the page. It should not prompt the user when I try and save/delete or update the page:

var dataUpdated = false;

$(document).ready(function() {
    SetupChangeEventOnAllInputElementsAndSetGlobalFlag();
})

function SetupChangeEventOnAllInputElementsAndSetGlobalFlag() {
    $(':input').change(function() {
        dataUpdated = true;

        window.onbeforeunload = function(evt) {

            var e = e || window.event;

            // For IE and Firefox
            if (e) {
                if (DetermineSubmit(evt) == true)
                    return;
                else
                    e.returnValue = 'You have not saved your changes - OK to ignore or Cancel to remain on this page?';
            }
            else {
                // For Safari
                if (DetermineSubmit(evt) == true)
                    return
                else
                    return 'You have not saved your changes - OK to ignore or Cancel to remain on this page?';
            }
        }

    });

}

//Determine if the original event is a submit button/control that triggered the window unload
function DetermineSubmit(evt) {
    if ($(evt.explicitOriginalTarget).is(':submit')) {
        return true;
    }
   
    return false;
}

jQuery disable button intercepts Request Object

Scenario: Hijack all my save buttons via the script below to override the value, from Save to Saving...., and then also disabling the button so they cannot hit it 1000 times.

$(document).ready(function() {
   form.find(':submit').each(function() {
      $(this).attr("disabled", "disabled").val("Saving....");
   });
});

The Issue: I have several submit type buttons on the page, like Save, Sand and Proceed, Delete, etc, so I use the Request.Form object to see what button was pressed to decide what to do. Well, the disable of the button by jQuery removes it from the Reuquest stream, even though it is only disabled after the click event has occurred, how strange.

The Solution: I don't know what the solution is other than removing the disable as below. Any ideas?
$(document).ready(function() {
   form.find(':submit').each(function() {
      $(this).val("Saving....");
   });
});

Why does F10 (continue) in Visual Studio not work?

Scenario:

I'm debugging a (web) project in Visual Studio 2008. It is breaking and the first break point only, and thereafter when i hit F10 it ignores and subsequent break points and runs all the way through. Why is this happening? Couple of pointers before we discuss the solution

  • I have tried 'clean solution'.
  • Other breakpoints sometimes(!) skipped, even in the same method
  • Make sure that you're in Debug mode not in Release.
  • There could be an exception while executing the instruction in question. Try enabling all exceptions to break into debugger and check.
The solution may be:

Tools -> Options -> Debugging -> General -> Un-check off Enable Just My Code.

Intercept a form submit with jQuery and prevent or allow submission

Goal: Intercept a form submit, find out what submit button was clicked/invoked and decide to prevent the submission or continue to submit.

Solution:
$(document).ready(function() {
    $("form").submit(function(e) {
        if (e.originalEvent.explicitOriginalTarget.id == "myButton") {
            if (some status is true continue to submit the form)
                return true;
                //If the status above is false continue to prompt the user if they want to submit or not
            var ok = confirm('Do you really want to save your data?');
            if (ok) {               
                return true;
            }
            else {
                //Prevent the submit event and remain on the screen
                e.preventDefault();
                return false;
            }
        }
    });

    return;
});

Prevent repeated clicks on submit button

Scenario: The user wants to save something and hits the Save button (type=submit). The event performs an Ajax call to send the request to the server. The user, being unaware or not sure if their request is being processed or if they clicked the Save button properly, click it again, and again, causing several Ajax requests, which could be a real problem, if the update is to, for example, transfer funds to your ex-girlfriend's account

The solution: Prevent the user from being able to click the Save button or to when they do to ignore it.

$(document).ready(function() {
    $("form").submit(function(e) {
        if ($('form').valid()) {
            $(':submit', this).each(function() {
                if ($(this).attr('value') == 'Save') {
                    $(this).attr("disabled", "disabled").val("Saving....");
                }
            });
        }
    });
});


Couple of pointers:
  • The button being pressed is of type submit
  • The attr of the button gets disabled so the user cannot hit it again and again, and since the form is submitted there is no need for enabling it again.
  • In this example I have also overridden the value of the button to indicate that the form is being saved
  • In this example all submit buttons are impacted ($(':submit', this))
If you want to target only a specific button:

$(document).ready(function() {
    $("#myButton").submit(function(e) {
        $('#myButton', this).attr("disabled", "disabled").val("Processing....");
    });
});



Oops, this does not work!!!!!!!!!!!!!!!!

The reason being is that the submit action is attached to the form not the "myButton". In order to perform the above and find out which button was pressed and take appropriate action do:

    $("form").submit(function(e) {
        if (e.originalEvent.explicitOriginalTarget.id == "myButton") {
            //Do something
        }

    });

jQuery AutoComplete in ASP.NET MVC Framework

Goal:

jQuery AutoComplete in ASP.NET MVC Framework with callback to customize result


Platform/Environment:

  • Asp.Net Mvc version 1
  • jQuery 1.3.2
  • Autocomplete - jQuery plugin 1.0.2

Quick Solution:


Here I am simply returning a list of account names:

    $('#Name').autocomplete(
        $('#ajaxListMatchingAccountNamesUrl').val(), { delay: 10, minChars: 3, matchSubset: 1, matchContains: 1, cacheLength: 10, autoFill: true, mustMatch: false, selectFirst: true, max: 15 }
    );

ajaxListMatchingAccountNamesUrl - this is a hidden input control in my master page that contains the url that I set as follows so as to allow the Mvc framework to set it dynamically:

<input id="ajaxListMatchingAccountNamesUrl" type="hidden" value="<%=Url.RouteUrl(new {controller = "Account", Action = "GetMatchingAccounts"})%>" />

Here is the C# controller action:

        [AcceptVerbs(HttpVerbs.Get)]
        public string GetMatchingAccounts(string q)
        {
            if (String.IsNullOrEmpty(q))
                return null;

            var sb = new StringBuilder();
            foreach (AccountNameIdDTO dto in _accountRepository.SearchForAccountsStartingWithNameSuffixKey(q))
            {
                sb.AppendLine(dto.Name);
            }
            return sb.ToString();
        }

Complex Solution:

A situation where my account names may be the same for different acounts. In this scenario I let the server-side action append the unique ID to the name, surrounded by brackets: My Account Name (23). This way when the user selects the account, I store the name in the textbox and the ID is parsed out and stored in a protected/readonly textbox.

    var $accountMaintenanceWrapper = $('div#AccountMaintenanceWrapper');
    $accountMaintenanceWrapper.find("#MasterAccount").autocomplete(
        $('#ajaxListMatchingAccountNamesWithIdSuffixUrl').val(),
        {
            delay:10,
            minChars:3,
            matchSubset:1,
            matchContains:1,
            cacheLength:10,
            autoFill:true,
            mustMatch: false,
            selectFirst : true,
            max: 15,
            formatResult: function(row, i, total) //this is the actual value that will be placed inside the textbox
            {
                //Parse out the ID suffix in brackets and place only the account name itself into the textbox for the name
                $accountMaintenanceWrapper.find('#MasterAccountId').val(i.substring(i.indexOf('(')+1,i.indexOf(')')));
                return i.substring(0,i.indexOf('('));
            }
        }
    );
   
    $accountMaintenanceWrapper.find("#MasterAccount").result(SetupCallBackForMasterAccount).next().click(function() {
            $(this).prev().search();
    });
   
    //When the auto complete textbox is empty, delete the key code from the text
    $accountMaintenanceWrapper.find("#MasterAccount").bind('keyup',function() {
        if ($(this).val() == '')
        {
            $accountMaintenanceWrapper.find('#MasterAccountId').val('')
        }
    });


//This function parses the matched auto complete value's suffix key (in between parenthesis)
function SetupCallBackForMasterAccount(event, data, formatted) {
    $('#MasterAccountId').val( !data ? " " : formatted.substring(formatted.indexOf('(')+1,formatted.indexOf(')')));
}

Here is the C# code controller action:

        [AcceptVerbs(HttpVerbs.Get)]
        public string GetMatchingAgentsWithIdSuffix(string q)
        {
            if (String.IsNullOrEmpty(q))
                return null;

            var sb = new StringBuilder();
            foreach (AccountNameIdDTO dto in _accountRepository.SearchForAccountsStartingWithNameSuffixKey(q))
            {
                if ((Repository<IAccount>.Get(dto.Id) as Agency) != null)
                    sb.AppendLine(dto.Name + "(" + dto.Id + ")");
            }
            return sb.ToString();
        }


Couple of pointers:

  • $accountMaintenanceWrapper - I declare this variable as I am referencing this container several times and to speed performance let jQuery find it and set the reference only once.
  • MasterAccountId - this is the readonly textbox that will contain the value of the unique ID
  • MasterAccount - this is the textbox where the user enters the name of the account
  • minChars:3 - Starts the search after/on three characters
  • selectFirst : true - if the user does not click on the name and simply tabs out will select the first one